Let me start by saying that this is the very first time I’ve worked with Powershell. I’ve been asked to take over the maintenance of a startup script that is used to join the station to the (samba4) domain.
After reviewing the script I found enough bugs to want to do a major rewrite, but for the purpose of this thread, I’m focusing on the section that retrieves the workstation’s IP address.
Here’s the original code as it is now.
function Wait-Network ($tries) {
while (1) {
# Get a list of DHCP-enabled interfaces that have a
# non-$null DefaultIPGateway property.
$x = gwmi -class Win32_NetworkAdapterConfiguration `
-filter IPEnabled=TRUE
# If there is (at least) one available, exit the loop.
if ( ($x | measure).count -gt 0 ) {
break
}
# If $tries > 0 and we have tried $tries times without
# success, throw an exception.
if ( $tries -gt 0 -and $try++ -ge $tries ) {
Write-TheLog("Network unavailable after $try tries.")
New-UserMessage "No Network Access" "This station was unable to find an active network connection."
Exit
}
# Wait one second.
start-sleep -s 1
}
}
$NICs = Get-WMIObject Win32_NetworkAdapterConfiguration `
where{$_.IPEnabled -eq "TRUE"}
$NICS | Foreach {
$_.EnableDHCP()
}
start-sleep -s 15
Wait-Network(30)
$IPAddrs = (Get-WMIObject Win32_NetworkAdapterConfiguration -Filter "IPEnabled = True").IPAddress
forEach($i in $IPAddrs)
{
if(-not $i.Contains("::"))
{
$stationIP = $i
}
}
The main (but not only problem) is that it loops over all interfaces and uses the IP of the last interface that doesn’t have an IP6 address, which may or may not be the correct interface.
I need to fix that bug and extend functionality to retrieve additional network info. Here is the function I worked up based on examples I found while researching powershell syntax.
function Get-HostInfo
{
Get-HostInfo -ComputerName TESTPC
IPaddress : 10.100.0.119
FQDN : TESTPC.company.com
DHCPEnabled : True
Hostname : TESTPC
GW : 10.100.0.1
MACaddress : 00:1C:C0:A3:6E:0A
.TODO
- If DHCPEnabled is FALSE on the desired interface, enable it
and make a recursive call to the function to make sure
it is retrieving the allocated DHCP reservation IP address.
- Extend the function to also be able to get remote host info
.Author
Ron Bergin
me@company.com
#>
[CmdletBinding()]
Param
(
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true
)
]
[string]$ComputerName
)
Begin { }
Process {
$FQDN = (Get-WmiObject win32_computersystem).DNSHostName + '.' + (Get-WmiObject win32_computersystem).Domain
#$FQDN = $ComputerName + '.' + (Get-WmiObject win32_computersystem).Domain
$interfaces = Get-WmiObject -class 'Win32_NetworkAdapterConfiguration' -computername $ComputerName | Where{ $_.IpEnabled -Match 'True' }
Foreach ($interface in $interfaces) {
if ($interface.IPAddress -match '^10.') {
$ip = $interface.IPAddress[0]
$GW = $interface.DefaultIPGateway[0]
$DHCP = $interface.DHCPEnabled
$MAC = Get-CimInstance win32_networkadapterconfiguration | Where {$_.Description -eq $interface.Description} | select MACaddress
break
}
}
$hostinfo = @{
'Hostname' = $ComputerName
'FQDN' = $FQDN
'IPaddress' = $ip
'GW' = $GW
'MACaddress' = $MAC.MACaddress
'DHCPEnabled' = $DHCP
}
$host_info = New-Object -TypeName PSObject -Property $hostinfo
}
End { $host_info }
}
$host_info = Get-HostInfo -ComputerName $env:computername
Write-Output $host_info
Questions:
-
Is this a good (best practice) approach or is there a better approach?
-
What adjustments do I need to make to have it be more generic so that I can retrieve the same info from a remote host? My goal is to move the function into a module so that it can be used in other scripts.