在Powershell中拆分WMI对象
我是PowerShell的新手,我尝试从客户端读取一些监视器/显示信息 我编写了以下脚本:在Powershell中拆分WMI对象,powershell,scripting,wmi,wmi-query,Powershell,Scripting,Wmi,Wmi Query,我是PowerShell的新手,我尝试从客户端读取一些监视器/显示信息 我编写了以下脚本: param( [string]$ComputerName ) $objWMi = get-wmiobject -namespace root\WMI -ComputerName $ComputerName -class WmiMonitorID | select WeekOfManufacture, YearOfManufacture, UserFriendlyName, SerialNumberID,
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
调用,并返回如下内容:
1:P22W-5 ECO | FUS | YE7XXXXX | 46 | 2008
就像一个符咒,正是我需要的。有一个例外:如果某个客户端连接了多个监视器,脚本将返回如下内容:
1:HP E272qHP E272q | HWPHWP | CNKXXCCNKYYYY | 40 40 | 2015
如果有多个监视器和输出,如何修改输出以分割结果
1:HP E272q | HWP | CNKXXXX | 40 | 2015 2:HP E272q | HWP | CNKXXXX | 40 | 2015
变量包含所有监视器的信息,我不知道如何避免这种情况,也不知道如何将其拆分为每个变量的一个值。
任何想法都非常感谢
编辑:我需要像上面那样在一行中返回结果,因为我将此结果馈送给另一个程序。检查此脚本:
它不像您那样处理文本的转换,但是用您已有的代码很容易纠正
此修改应该非常接近您需要的内容:
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"
}
查看此脚本:
它不像您那样处理文本的转换,但是用您已有的代码很容易纠正
此修改应该非常接近您需要的内容:
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"
}
我觉得有必要增加一个额外的答案。请记住,
写主机
不是一条好路。就像唐·琼斯那样,它会杀死小狗,有很多更好的方法来实现你想要的
首先,通过生成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
。我觉得有必要添加一个额外的答案。请记住,写主机
不是一条好路。就像唐·琼斯那样,它会杀死小狗,有很多更好的方法来实现你想要的
首先,通过生成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"
正如您所看到的,当仅使用编写主机时,所有这些事情都会很困难。希望上面的例子能更清楚地说明为什么在这种情况下不应该使用写主机。我试图提出以下内容作为对DarkLite1答案的修改,但显然有人认为这是“故意破坏性的”,并拒绝了它
为了回答您的问题,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($Result中的monitor){$monitor.ToString()}
我试图提出以下内容作为对DarkLite1答案的修改,但显然有人认为这是“故意破坏性的”,并拒绝了它
为了回答您的问题,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($Result中的monitor){$monitor.ToString()}
谢谢。我以前看过这个剧本。不幸的是,我需要在一行中返回结果,因为我在另一个程序中处理结果…编辑我的帖子以澄清问题。我还在脚本中放置了一个foreach
循环write host
。这也会输出包含两个条目的行,但只输出两次……我更新了代码,以便在一行中输出。围绕变量赋值的“foreach”循环是造成问题的原因。耶。我也尝试过在变量周围使用foreach
循环,但没有同时删除foreach对象。谢谢我添加了一个小函数来进行字符串转换。这样,如果得到一个空值,它就不会抛出错误。不过,DarkLite1的解决方案更为优雅。所以理想情况下,我会把这个功能和他的回答结合起来。谢谢。我以前看过这个剧本。不幸的是,我需要在一行中返回结果,因为我在另一个程序中处理结果…编辑我的帖子以澄清问题。我还在脚本中放置了一个foreach
循环write host
。这也会输出包含两个条目的行,但只输出两次……我更新了代码,以便在一行中输出。围绕变量赋值的“foreach”循环是造成问题的原因。耶。我也尝试过在变量周围使用foreach
循环,但没有同时删除foreach对象。谢谢我添加了一个小函数来进行字符串转换。这样,如果得到一个空值,它就不会抛出错误。不过,DarkLite1的解决方案更为优雅。因此,理想情况下,我会将该功能与他的回答结合起来。谢谢!我不知道这件事。我正在用另一个程序来处理这个脚本,这个程序正在执行这个脚本,并且希望结果是一个字符串打印到标准输出(在一行中)。不客气,希望您学到了一些东西。也可以输出到字符串:$Result |选择${N='string';E={“$($.FriendlyName)$($.SN)|$($.ManufacturerName)|$($.ManufacturingWeek)|$($.ManufacturingYear)}}}输出字符串
,或者如果您的意思是在一行上查看内容,也可以执行$Result>格式表
。谢谢!哈希表似乎不起作用,它总是从localhost返回信息……还有没有办法只返回这一行?第一个示例输出字符串