使用PowerShell 3.0,我使用Invoke-Command cmdlet将xmlElement传递给scriptblock。问题是我认为scriptBlock是作为arrayList而不是xmlElement接收参数(实际上,我知道在我注销ArrayList
时收到的参数是$service.GetType()
。
这是我的XMLElement:
<Service>
<ServiceName>Spooler</ServiceName>
<Startup>Disabled</Startup>
</Service>
这是我的scriptBlock:
$scptModifyService = {
param (
$service
);
Set-Service -Name $service.ServiceName -StartupType $service.Startup;
}
这是我调用scriptBlock的代码:
## Modify remote Services:
foreach($service in $XML.QCSettings.Services.Service) {
Invoke-Command -ScriptBlock $scptModifyService -ComputerName $ComputerName -ArgumentList $service;
}
据我所知,Invoke-Command cmdlet(get-help invoke-command)是ArguementList可以将一个对象作为输入,所以我认为这不是我如何调用scriptblock的问题上面的'foreach'循环。希望这是有道理的。
有没有人对如何将我的scriptblock中的param捕获为xmlElement而不是ArrayList
有任何想法?
我已经尝试了几件事(在我的scriptblock中):
param( $service = [xml]Get-Content args[0] );
该代码的其他变体。
答案 0 :(得分:1)
从你所展示的内容来看,我看不到scriptblock是如何获得ArrayList的,但你仍然能够做到这一点。 ArrayList是否包含正确的XmlElements?如果是这样,您只需处理一个或多个服务条目就可以使您的功能更加健壮:
$scptModifyService = {
param (
[Xml.XmlElement[]]$service
);
foreach ($s in $service) {
Set-Service -Name $s.ServiceName -StartupType $s.Startup;
}
}
然后你应该可以这样称呼它:
Invoke-Command -ScriptBlock $scptModifyService -ComputerName $ComputerName -ArgumentList $XML.QCSettings.Services.Service
答案 1 :(得分:0)
使用PowerShell的[xml]
加速器和动态属性时必须小心。看起来像普通的XML文档对象模型会被转换为ArrayList
和其他令人讨厌的对象。
果然,当我将XML加载到DOM中,并在GetType()
元素上调用Service
时,我得到Object[]
:
> $xml = [xml]'<QCSettings><Services><Service /><Service /></Services></QCSettings>'
> $xml.QCSettings.Services.Service.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
由于您使用的是PowerShell 3,因此可以使用using
范围来引用远程脚本块中的XML块:
$services = $xml.QCSettings.Services.Service
Invoke-Command -ScriptBlock {
$using:services | ForEach-Object {
Set-Service $_.ServiceName -StartupType $_.StartupType
}
}
由于此代码传递了所有服务对象,因此您只需登录一次计算机,而在此之前,您每个服务都登录一次。
如果您无法使用using
范围,我会使用ArrayList
并编写您的脚本块以接受对象列表:
$scptModifyService = {
param (
[Object[]]
$service
);
$service | ForEach-Object {
Set-Service -Name $_.ServiceName -StartupType $_.StartupType
}
}
$XML.QCSettings.Services.Service |
ForEach-Object {
Invoke-Command -ScriptBlock $scptModifyService -ComputerName $ComputerName -ArgumentList $_
}