我有一个名为Get-InstalledApps
的函数,该函数连接到使用-computers
参数列出的所有计算机,该函数通过管道接受输入。
将计算机名称传递给函数时有两个问题:
(a)我有一个可以传递给它的CSV文件,但是它解析这样的值:@{computername=HOSTNAME}
,而不只是HOSTNAME
。
(b)相反,当从Get-ADComputer -Filter *
进行管道传输时,它只是获取上次传递的计算机名称。
这是我的职能:
function Get-InstalledApps {
Param (
[CmdletBinding()]
[Parameter(ValueFromPipeline=$true)]
[Alias('name')]
[string[]]$computers = $env:COMPUTERNAME
)
foreach($computer in $computers){
write-verbose -verbose -message "`nStarting scan on $computer"
Invoke-Command -Computername $computer -ErrorAction SilentlyContinue -ErrorVariable InvokeError -Scriptblock {
$installPaths = @('HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall','HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall')
Get-ChildItem -Path $installPaths | Get-ItemProperty | Sort-Object -Property DisplayName | Select-Object -Property DisplayName, DisplayVersion, Publisher, UninstallString, Version
}
if ($invokeerror){
Write-Warning "Could not communicate with $computer"
}
}
}
更新:此问题已解决。这是那些想要的人的要点:
https://gist.github.com/TylerJWhit/f596c307cf87540842281a8a20149f9a
答案 0 :(得分:0)
关于(a):
如果您的函数看到的是@{computername=HOSTNAME}
而不是HOSTNAME
,则表示您正在执行以下操作:
Import-Csv ... | Select-Object ComputerName | Get-InstalledApps
代替必需的:
Import-Csv ... | Select-Object -ExpandProperty ComputerName | Get-InstalledApps
请注意-ExpandProperty
开关,这是从输入中提取单个属性 value 所必需的;没有它,您将获得具有该属性的对象-有关更多信息,请参见this answer。
关于(b):
为了接受逐个对象管道输入,您的函数必须具有process { ... }
块:
function Get-InstalledApps {
Param (
[CmdletBinding()]
[Parameter(ValueFromPipeline=$true)]
[Alias('name')]
[string[]]$computers = $env:COMPUTERNAME
)
process { # This ensures that the following code is called for each input object.
foreach ($computer in $computers){
# ...
}
}
}
请参见Get-Help about_Functions_Advanced
。
请注意,如果您只希望函数通过管道(... | Get-InstalledApps
)接收计算机名称列表,而不是通过 by参数({ {1}}),您可以将Get-InstalledApps -Computers ...
参数声明为-Computers
(而不是 array ),从而消除了内部[string]
循环的需要foreach
块。
有关这种差异的讨论,请参见this GitHub issue。