5

使用 PowerShell 3.0,我使用 Invoke-Command cmdlet 将 xmlElement 传递给脚本块。问题是我认为 scriptBlock 将参数作为 arrayList 而不是作为 xmlElement 接收(实际上,我知道接收到的参数是ArrayList我注销时的$service.GetType())。

这是我的 XMLElement:

<Service>
    <ServiceName>Spooler</ServiceName>
    <Startup>Disabled</Startup>
</Service>

这是我的脚本块:

$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 可以将对象作为输入,所以我认为这不是我如何在“foreach”中调用脚本块的问题'上面的循环。希望这有点道理。

有没有人对如何将我的脚本块中的参数捕获为 xmlElement 而不是作为 xmlElement 有任何想法ArrayList

我已经尝试了几件事(在我的脚本块中):

param( $service = [xml]Get-Content args[0] );

以及该代码的其他变体。

4

2 回答 2

1

从您所展示的内容来看,我看不到脚本块如何获取 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
于 2013-07-05T16:34:21.053 回答
1

[xml]使用 PowerShell 的加速器和动态属性时必须小心。看起来像普通 XML 文档对象模型的东西会被转换成ArrayList其他令人讨厌的对象。

果然,当我将您的 XML 加载到 DOM 中并调用元素时,我得到GetType()一个:ServiceObject[]

> $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 $_
    }
于 2013-07-09T08:34:58.477 回答