PowerShell';如果';条件
下面是一个简短的PowerShell简介,用来获取设备的IP地址、服务标签和设备上任何活动MAC地址的MAC地址(活动表示存在连接) 无论如何,如果我不使用PowerShell';如果';条件,powershell,if-statement,Powershell,If Statement,下面是一个简短的PowerShell简介,用来获取设备的IP地址、服务标签和设备上任何活动MAC地址的MAC地址(活动表示存在连接) 无论如何,如果我不使用if语句,这将非常有效,但如果我使用,它将只执行第一行: testconnection$computername-count 1 |选择@Name=“computername”表达式={$\u.Address},Ipv4Address 如果设备已打开。。。设备的最后一行已关闭 写入主机“设备脱机” 这是我的小PowerShell“脚本”:
if
语句,这将非常有效,但如果我使用,它将只执行第一行:
testconnection$computername-count 1 |选择@Name=“computername”表达式={$\u.Address},Ipv4Address
如果设备已打开。。。设备的最后一行已关闭
写入主机“设备脱机”
这是我的小PowerShell“脚本”:
$computername=读取主机“输入计算机名”
$online=测试连接-Computername$Computername-BufferSize 16-计数1-安静
如果($online-eq“True”){
测试连接$computername-count 1 |选择@Name=“computername”表达式={$\u.Address},Ipv4Address
获取WmiObject win32_SystemEnclosure-computername$computername |选择serialnumber
获取wmiobject-类“Win32_NetworkAdapterConfiguration”-computername$computername |其中{$\u.IpEnabled-匹配“True”}
}否则{
写入主机“设备处于脱机状态”
}
为什么会发生这种情况?我可能做错了什么?PowerShell中的布尔变量是
$true
和$false
<代码>如果应为:
if ($online -eq $true) {
或
testconnection-Quiet
返回布尔值,而不是字符串。如果您希望明确,请尝试if($online)
或if($online-eq$true)
试试这个:
$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"
}
注意:我不是建议你在最后的脚本中保留这段代码;用这个来了解幕后发生了什么
根据评论;使用$true
而不是“true”
,就好像两者都是真实的一样,使用错误的类型会导致对语言的错误理解/一些非常奇怪的错误,你会发现像if($true-eq“false”){write output“嗯,这是不寻常的”}
这样的行会导致一些奇怪的行为
此外,对于任何逻辑返回值,您可能希望将写主机
替换为写输出
,或者对于任何信息性/调查性输出,您可能希望将写详细
/写调试
替换为写输出
;然后使用适当的开关/首选项调用代码。。。但这与你的问题无关。关于这方面的更多信息,请参阅
更新 根据评论,您看到的问题是一个bug,明白了: 如果此代码产生的数据仅显示在控制台中,则可以通过显式调用
格式表
命令来避免此问题:
$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"
}
如果您需要输出到其他地方的管道以供使用,则一切正常(即没有格式表
块);正在将对象正确写入管道;问题很简单,当同时显示所有结果时,第一个对象会导致PowerShell创建列ComputerName
和Ipv4Address
,并且PowerShell随后会尝试显示以下对象的那些属性,尽管这些对象没有这些属性。也就是说,这可以通过将不同的对象类型放入自定义对象的不同属性中以便于参考而得到改进。比如说,
$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"
}
注意:使用
$true
而不是“true”
;第一个是布尔值;第二个是字符串。如果我理解了你的问题,你是说当计算机联机时,你看不到序列号或网络适配器信息;是这样吗?如果是这样的话,对远程计算机运行这些WMI查询可能会出现权限问题?如果您自己运行这些语句,会发生什么?另外,您的$ErrorActionPreference
设置为什么(即可能设置为SilentlyContinue
,这样就不会显示异常)?@jasonnell不,我不这么认为@{Name=“Computername”…只需将“Address”一词更改为“Computername”,如该行其余部分所述If
语句是有意义的;我要问的是,如果没有该语句,它是如何理解问题的;即If
语句是导致问题的,还是与问题无关(这似乎更有可能)/是否只是调用get wmiobject
的代码没有生成任何输出;很可能是因为我们没有看到一些错误。在Powershell$true中-eq“true”
也是有效的。无论出于何种原因,字符串true或false都可以与bool进行比较。“true”
是truthy
值(),但“false”
也是真实的(例如,run:$true-eq“false”
),因此最好总是使用定义的值/在运行此类检查时要小心。“false”也是真实的,这很奇怪。@jasonnell;这是因为“false”这个词“仅对我们人类有意义;从PowerShell比较的角度来看,它将其转换为布尔值以执行比较,而非零长度的字符串根据定义转换为true。“false”-eq$true
给出false,因为它将$true
转换为字符串,“true”
,因此“false”-eq”true”
的计算结果为false。为了避免这种混淆,在进行比较时始终使用正确的类型。这对您有用吗?您有服务标签和Mac地址吗?@lukezemet;最初我没有尝试过。我现在添加了类型定义,以确保返回1个对象时,对象仍然是数组,因此仍然有计数
属性:例如[PSObject[]$systemEnclosures
。约翰:我很抱歉一开始就把我们引向了错误的道路:我认为,正如我后来解释的那样,您所描述的行为实际上是经过设计的。@PetSerAl的答案中解释的隐式格式表
的异步行为也可能是一个问题,但它与这个问题无关。不用担心,这是一个问题nks@mklement0.将继续
$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"
}