在 Powershell 中拆分 WMI 对象
Split up WMI Objects in Powershell
我是 PowerShell 的新手,我尝试阅读来自客户的一些 monitor/display 信息。
我整理了这个脚本:
param(
[string]$ComputerName
)
$objWMi = get-wmiobject -namespace root\WMI -ComputerName $ComputerName -class WmiMonitorID | select WeekOfManufacture, YearOfManufacture, UserFriendlyName, SerialNumberID, ManufacturerName
$Userfn = ForEach-Object {($objWMi.UserFriendlyName -ne 0 | foreach {[char]$_}) -join"";}
$SerialNum = ForEach-Object {($objWMi.SerialNumberID -ne 0 | foreach {[char]$_}) -join"";}
$ManuName = ForEach-Object {($objWMi.ManufacturerName -ne 0 | foreach {[char]$_}) -join"";}
$Weekom = $objWMi.WeekOfManufacture
$Yearom = $objWMi.YearOfManufacture
Write-Host "1: $Userfn | $ManuName | $SerialNum | $Weekom | $Yearom"
Exit 0
用 .\myscript.ps1 -ComputerName clientdnsname
和 returns 调用它是这样的:
1: P22W-5 ECO | FUS | YE7XXXXX | 46 | 2008
。
效果很好,正是我所需要的。有一个例外:如果某些客户端有多个监视器附加脚本 returns 是这样的:
1: HP E272qHP E272q | HWPHWP | CNKXXXXCCNKYYYY | 40 40 | 2015 2015
如果有多个监视器和输出,我如何修改输出以拆分结果
1: HP E272q | HWP| CNKXXXX | 40 | 2015 2: HP E272q | HWP| CNKXXXX | 40 | 2015
变量包含所有监视器的信息,我不知道如何避免这种情况或如何将其拆分为每个变量的一个值。
非常感谢任何想法!
编辑:我需要像上面那样在 一行 中返回结果,因为我将其提供给另一个程序。
查看此脚本:http://www.activexperts.com/admin/scripts/wmiscripts/powershell/0073/
它不像您那样处理文本转换,但使用您已有的代码很容易纠正。
此修改应该非常接近您的需要:
function byteArrayToString($byteArray)
{
if ($byteArray.Count -gt 0){
return ($byteArray -ne 0 | foreach {[char]$_}) -join""
}
return "N/A"
}
$strComputer = "."
$objWMi = get-wmiobject -namespace root\WMI -computername localhost -Query "Select * from WmiMonitorID"
foreach ($obj in $objWmi)
{
$Userfn = byteArrayToString($obj.UserFriendlyName)
$SerialNum = byteArrayToString($obj.SerialNumberID)
$ManuName = byteArrayToString($obj.ManufacturerName)
$Weekom = $obj.WeekOfManufacture
$Yearom = $obj.YearOfManufacture
Write-Host "1: $Userfn | $ManuName | $SerialNum | $Weekom | $Yearom"
}
我觉得有必要补充一个答案。请记住 Write-Host
不是正确的选择。正如 Don Jones explains 它杀死了小狗,还有很多更好的方法来实现你想要的。
首先,通过生成 PSCustomObject
你可以做更多的事情。
一些例子:
Function Get-MonitorInfo {
Param (
[String]$ComputerName = $env:COMPUTERNAME
)
# For ease of reading the code we create a hashtable which we use wit 'Get-WmiObject', this is called 'Splatting'
$WmiParams = @{
Namespace = 'root\WMI'
ComputerName = $ComputerName
Class = 'WmiMonitorID'
}
# First we collect all the results in one variabla
$Objects = Get-WmiObject @WmiParams | Select-Object WeekOfManufacture, YearOfManufacture,
UserFriendlyName, SerialNumberID, ManufacturerName
# Then for each object in the variable '$Objects' we generate one line of output (an object)
foreach ($Object in $Objects) {
# The generated object will contain the following
[PSCustomObject]@{
FriendlyName = ($Object.UserFriendlyName | ForEach-Object {[Char]$_}) -join ''
SN = ($Object.SerialNumberID | ForEach-Object {[Char]$_}) -join ''
ManufacturerName = ($Object.ManufacturerName | ForEach-Object {[char]$_}) -join ''
ManufacturingWeek = $Object.WeekOfManufacture
ManufacturingYear = $Object.YearOfManufacture
}
}
}
$Result = Get-MonitorInfo
# List all monitors:
$Result
# Only list Monitors with a FriendlyName starting with HP:
$Result | where {$_.FriendlyName -like 'HP*'}
# Only list Monitors with a FriendlyName starting with HP and show me the SN:
$Result | where {$_.FriendlyName -like 'HP*'} | Select-Object SN
# Count how many monitors we have on one machine:
$Result.Count
# Export everything to a file
$Result | Out-File -FilePath "$env:TEMP\Monitors.txt"
Start-Process "$env:TEMP\Monitors.txt"
如您所见,仅使用 Write-Host
时,所有这些事情都会很困难。希望上面的例子让你更清楚为什么你不应该在这种情况下使用 Write-Host
。
我试图提出以下建议作为对 DarkLite1 答案的修改,但显然有人认为它是 "deliberately destructive" 并拒绝了它。 . .
为了回答你的问题,duenni,以下对 DarkLite1 代码的修改将使你能够以你正在寻找的格式输出数据。
Function byteArrayToString($byteArray)
{
if ($byteArray.Count -gt 0){
return ($byteArray -ne 0 | foreach {[char]$_}) -join""
}
return "N/A"
}
Function Get-MonitorInfo {
Param (
[String]$ComputerName = $env:COMPUTERNAME
)
# For ease of reading the code we create a hashtable which we use wit 'Get-WmiObject', this is called 'Splatting'
$WmiParams = @{
Namespace = 'root\WMI'
ComputerName = $ComputerName
Class = 'WmiMonitorID'
}
# First we collect all the results in one variabla
$Objects = Get-WmiObject @WmiParams | Select-Object WeekOfManufacture, YearOfManufacture,
UserFriendlyName, SerialNumberID, ManufacturerName
# Then for each object in the variable '$Objects' we generate one line of output (an object)
foreach ($Object in $Objects) {
# The generated object will contain the following
[PSCustomObject]@{
FriendlyName = byteArrayToString($Object.UserFriendlyName)
SN = byteArrayToString($Object.SerialNumberID)
ManufacturerName = byteArrayToString($Object.ManufacturerName)
ManufacturingWeek = $Object.WeekOfManufacture
ManufacturingYear = $Object.YearOfManufacture
} | Add-Member -MemberType ScriptMethod -Name ToString -Force -Value {
"1: $($this.FriendlyName) | $($this.ManufacturerName) | $($this.SN) | $($this.ManufacturingWeek) | $($this.ManufacturingYear)"
} -PassThru
}
}
$Result = Get-MonitorInfo
# List all monitors:
$Result
# List all monitors as formatted strings
foreach ($monitor in $Result) {$monitor.ToString()}
# Only list Monitors with a FriendlyName starting with HP:
$Result | where {$_.FriendlyName -like 'HP*'}
# Only list Monitors with a FriendlyName starting with HP and show me the SN:
$Result | where {$_.FriendlyName -like 'HP*'} | Select-Object SN
# Count how many monitors we have on one machine:
$Result.Count
# Export everything to a file
$Result | Out-File -FilePath "$env:TEMP\Monitors.txt"
Start-Process "$env:TEMP\Monitors.txt"
新函数调用方式如下:
foreach ($monitor in $Result) {$monitor.ToString()}
我是 PowerShell 的新手,我尝试阅读来自客户的一些 monitor/display 信息。
我整理了这个脚本:
param(
[string]$ComputerName
)
$objWMi = get-wmiobject -namespace root\WMI -ComputerName $ComputerName -class WmiMonitorID | select WeekOfManufacture, YearOfManufacture, UserFriendlyName, SerialNumberID, ManufacturerName
$Userfn = ForEach-Object {($objWMi.UserFriendlyName -ne 0 | foreach {[char]$_}) -join"";}
$SerialNum = ForEach-Object {($objWMi.SerialNumberID -ne 0 | foreach {[char]$_}) -join"";}
$ManuName = ForEach-Object {($objWMi.ManufacturerName -ne 0 | foreach {[char]$_}) -join"";}
$Weekom = $objWMi.WeekOfManufacture
$Yearom = $objWMi.YearOfManufacture
Write-Host "1: $Userfn | $ManuName | $SerialNum | $Weekom | $Yearom"
Exit 0
用 .\myscript.ps1 -ComputerName clientdnsname
和 returns 调用它是这样的:
1: P22W-5 ECO | FUS | YE7XXXXX | 46 | 2008
。
效果很好,正是我所需要的。有一个例外:如果某些客户端有多个监视器附加脚本 returns 是这样的:
1: HP E272qHP E272q | HWPHWP | CNKXXXXCCNKYYYY | 40 40 | 2015 2015
如果有多个监视器和输出,我如何修改输出以拆分结果
1: HP E272q | HWP| CNKXXXX | 40 | 2015 2: HP E272q | HWP| CNKXXXX | 40 | 2015
变量包含所有监视器的信息,我不知道如何避免这种情况或如何将其拆分为每个变量的一个值。 非常感谢任何想法!
编辑:我需要像上面那样在 一行 中返回结果,因为我将其提供给另一个程序。
查看此脚本:http://www.activexperts.com/admin/scripts/wmiscripts/powershell/0073/
它不像您那样处理文本转换,但使用您已有的代码很容易纠正。
此修改应该非常接近您的需要:
function byteArrayToString($byteArray)
{
if ($byteArray.Count -gt 0){
return ($byteArray -ne 0 | foreach {[char]$_}) -join""
}
return "N/A"
}
$strComputer = "."
$objWMi = get-wmiobject -namespace root\WMI -computername localhost -Query "Select * from WmiMonitorID"
foreach ($obj in $objWmi)
{
$Userfn = byteArrayToString($obj.UserFriendlyName)
$SerialNum = byteArrayToString($obj.SerialNumberID)
$ManuName = byteArrayToString($obj.ManufacturerName)
$Weekom = $obj.WeekOfManufacture
$Yearom = $obj.YearOfManufacture
Write-Host "1: $Userfn | $ManuName | $SerialNum | $Weekom | $Yearom"
}
我觉得有必要补充一个答案。请记住 Write-Host
不是正确的选择。正如 Don Jones explains 它杀死了小狗,还有很多更好的方法来实现你想要的。
首先,通过生成 PSCustomObject
你可以做更多的事情。
一些例子:
Function Get-MonitorInfo {
Param (
[String]$ComputerName = $env:COMPUTERNAME
)
# For ease of reading the code we create a hashtable which we use wit 'Get-WmiObject', this is called 'Splatting'
$WmiParams = @{
Namespace = 'root\WMI'
ComputerName = $ComputerName
Class = 'WmiMonitorID'
}
# First we collect all the results in one variabla
$Objects = Get-WmiObject @WmiParams | Select-Object WeekOfManufacture, YearOfManufacture,
UserFriendlyName, SerialNumberID, ManufacturerName
# Then for each object in the variable '$Objects' we generate one line of output (an object)
foreach ($Object in $Objects) {
# The generated object will contain the following
[PSCustomObject]@{
FriendlyName = ($Object.UserFriendlyName | ForEach-Object {[Char]$_}) -join ''
SN = ($Object.SerialNumberID | ForEach-Object {[Char]$_}) -join ''
ManufacturerName = ($Object.ManufacturerName | ForEach-Object {[char]$_}) -join ''
ManufacturingWeek = $Object.WeekOfManufacture
ManufacturingYear = $Object.YearOfManufacture
}
}
}
$Result = Get-MonitorInfo
# List all monitors:
$Result
# Only list Monitors with a FriendlyName starting with HP:
$Result | where {$_.FriendlyName -like 'HP*'}
# Only list Monitors with a FriendlyName starting with HP and show me the SN:
$Result | where {$_.FriendlyName -like 'HP*'} | Select-Object SN
# Count how many monitors we have on one machine:
$Result.Count
# Export everything to a file
$Result | Out-File -FilePath "$env:TEMP\Monitors.txt"
Start-Process "$env:TEMP\Monitors.txt"
如您所见,仅使用 Write-Host
时,所有这些事情都会很困难。希望上面的例子让你更清楚为什么你不应该在这种情况下使用 Write-Host
。
我试图提出以下建议作为对 DarkLite1 答案的修改,但显然有人认为它是 "deliberately destructive" 并拒绝了它。 . .
为了回答你的问题,duenni,以下对 DarkLite1 代码的修改将使你能够以你正在寻找的格式输出数据。
Function byteArrayToString($byteArray)
{
if ($byteArray.Count -gt 0){
return ($byteArray -ne 0 | foreach {[char]$_}) -join""
}
return "N/A"
}
Function Get-MonitorInfo {
Param (
[String]$ComputerName = $env:COMPUTERNAME
)
# For ease of reading the code we create a hashtable which we use wit 'Get-WmiObject', this is called 'Splatting'
$WmiParams = @{
Namespace = 'root\WMI'
ComputerName = $ComputerName
Class = 'WmiMonitorID'
}
# First we collect all the results in one variabla
$Objects = Get-WmiObject @WmiParams | Select-Object WeekOfManufacture, YearOfManufacture,
UserFriendlyName, SerialNumberID, ManufacturerName
# Then for each object in the variable '$Objects' we generate one line of output (an object)
foreach ($Object in $Objects) {
# The generated object will contain the following
[PSCustomObject]@{
FriendlyName = byteArrayToString($Object.UserFriendlyName)
SN = byteArrayToString($Object.SerialNumberID)
ManufacturerName = byteArrayToString($Object.ManufacturerName)
ManufacturingWeek = $Object.WeekOfManufacture
ManufacturingYear = $Object.YearOfManufacture
} | Add-Member -MemberType ScriptMethod -Name ToString -Force -Value {
"1: $($this.FriendlyName) | $($this.ManufacturerName) | $($this.SN) | $($this.ManufacturingWeek) | $($this.ManufacturingYear)"
} -PassThru
}
}
$Result = Get-MonitorInfo
# List all monitors:
$Result
# List all monitors as formatted strings
foreach ($monitor in $Result) {$monitor.ToString()}
# Only list Monitors with a FriendlyName starting with HP:
$Result | where {$_.FriendlyName -like 'HP*'}
# Only list Monitors with a FriendlyName starting with HP and show me the SN:
$Result | where {$_.FriendlyName -like 'HP*'} | Select-Object SN
# Count how many monitors we have on one machine:
$Result.Count
# Export everything to a file
$Result | Out-File -FilePath "$env:TEMP\Monitors.txt"
Start-Process "$env:TEMP\Monitors.txt"
新函数调用方式如下:
foreach ($monitor in $Result) {$monitor.ToString()}