Reputation: 31
Here is a quick little PowerShell blurp that is supposed to get the device's IP address, Service Tag, and MAC address of any active MAC addresses on the device (active meaning there is a connection).
Anyway, if I don't use an if
statement, this works perfectly, but if I do, it only executes the first line:
Test-Connection $computername -count 1 | select @{Name="Computername";Expression={$_.Address}},Ipv4Address
If the device is on... and the last line of the device is off.
Write-Host "Device is offline"
Here is my little PowerShell 'script':
$computername = Read-Host 'Enter Computer Name'
$online = Test-Connection -Computername $computername -BufferSize 16 -Count 1 -Quiet
IF ($online -eq "True") {
Test-Connection $computername -count 1 | select @{Name="Computername";Expression={$_.Address}},Ipv4Address
Get-WmiObject win32_SystemEnclosure -computername $computername | select serialnumber
Get-wmiobject -class "Win32_NetworkAdapterConfiguration" -computername $computername |Where{$_.IpEnabled -Match "True"}
} Else {
Write-Host "Device is offline"
}
Why does this happen? What might I be doing wrong?
Upvotes: 3
Views: 7247
Reputation: 24410
Try this:
$computername = Read-Host 'Enter Computer Name'
$online = Test-Connection -Computername $computername -BufferSize 16 -Count 1 -Quiet
IF ($online -eq $true) {
Write-Host "Device is online"
Test-Connection $computername -count 1 | select @{Name="Computername";Expression={$_.Address}},Ipv4Address
try {
[PSObject[]]$systemEnclosures = Get-WmiObject win32_SystemEnclosure -computername $computername -ErrorAction Stop
Write-Host "Found $($systemEnclosures.Count) System Enclosures"
$systemEnclosures | select serialnumber
[PSObject[]]$NetworkAdapterConfiguration = Get-wmiobject -class "Win32_NetworkAdapterConfiguration" -computername $computername -ErrorAction Stop
Write-Host "Found $($NetworkAdapterConfiguration.Count) Network Adapter Configurations"
$NetworkAdapterConfiguration = $NetworkAdapterConfiguration | Where{$_.IpEnabled}
Write-Host "Found $($NetworkAdapterConfiguration.Count) IP Enabled Network Adapter Configurations"
$NetworkAdapterConfiguration
} catch {
Write-Host "An Error Occurred"
Write-Host $_.ToString() #show exception info
}
} Else {
Write-Host "Device is offline"
}
NB: I'm not suggesting you keep this code in your final script; just use this to understand what's happening behind the scenes.
Per comments; use $true
instead of "true"
, as though both are truthy, using the wrong type will lead to a false understanding of the language / some really odd bugs down the line where you find that lines like if($true -eq "false") {write-output "Well, this is unusual"}
will cause some odd behaviour.
Also you may wish to look into replacing Write-Host
with Write-Output
for any logical return values, or Write-Verbose
/Write-Debug
for any informative/investigation outputs; then call the code with the appropriate switches / preferences... but that's unrelated to your issue. More on that is in Write-Host Considered Harmful.
Update
Per comments, the issue you're seeing is a bug gotcha: https://github.com/PowerShell/PowerShell/issues/4552
If the data coming out of this code is just to be displayed in the console, you can avoid this issue by explicitly calling the Format-Table
command:
$computername = Read-Host 'Enter Computer Name'
IF (Test-Connection -Computername $computername -BufferSize 16 -Count 1 -Quiet) {
Test-Connection $computername -count 1 | select @{Name="Computername";Expression={$_.Address}}, 'Ipv4Address' | Format-Table
Get-WmiObject win32_SystemEnclosure -computername $computername | select serialnumber | Format-Table
Get-wmiobject -class "Win32_NetworkAdapterConfiguration" -computername $computername | Where{$_.IpEnabled} | Format-Table
} Else {
Write-Host "Device is offline"
}
If you need the output to go to the pipeline for consumption elsewhere, all's good as it is (i.e. without the format-table
piece); the objects are being correctly written to the pipeline; the issue is simply that when it comes to displaying all of the results together, the first object causes PowerShell to create columns ComputerName
and Ipv4Address
, and PowerShell subsequently attempts to display those properties of the following objects, despite those not having such properties. That said, this could be improved by putting the different object types into different properties of a custom object for easy reference. For example,
$computername = Read-Host 'Enter Computer Name'
If (Test-Connection -Computername $computername -BufferSize 16 -Count 1 -Quiet) {
(new-object -TypeName PSObject -Property @{
ConnectionTest = Test-Connection $computername -count 1 | select @{Name="Computername";Expression={$_.Address}}, 'Ipv4Address'
SystemEnclosures = Get-WmiObject win32_SystemEnclosure -computername $computername | select serialnumber
NetworkAdapterConfigs = Get-wmiobject -class "Win32_NetworkAdapterConfiguration" -computername $computername | Where{$_.IpEnabled}
})
} Else {
Write-Host "Device is offline"
}
Upvotes: 2
Reputation: 512
Test-Connection -Quiet
returns a Boolean, not a string. Try if ($online)
or if ($online -eq $true)
if you want to be explicit.
Upvotes: 1
Reputation: 10019
Boolean variables in PowerShell are $true
and $false
. If
should be:
if ($online -eq $true) {
Or
if($online)
Upvotes: 2