-PipelineVariable无法按预期工作

时间:2018-11-02 15:56:05

标签: powershell

我有这个脚本,可以根据一个csv文件输入更改服务

Import-CSV .\SSAS_services.csv |
    ForEach-Object{
        Get-Service $_.Service -ComputerName $_.Server -PipelineVariable svc|
            Set-Service -Status $_.Task -StartupType $_.'Startup Type' -PassThru
    } |
    Select-Object MachineName, Name, Status, StartType, @{n='OldStatus';e={$svc.Status}}, @{n='OldStartType';e={$svc.StartType}} | 
    tee-object -FilePath '.\ChangeServices_LOG.txt' #-Append
Server,Service,Startup Type,Task
DCVPIM108,SQL Server Analysis Services (MSSQLSERVER),automatic,start
server2,"SQL Server Analysis Services (MSSQLSERVER), SQL Server Analysis Services (MSSQLSERVER) CEIP",Manual,stop

它工作得很好,除了我的-PipelineVariable svc工作不正常。如果在将服务更改为“运行”和“自动”之前将其“停止”和“手动”,则不会获得OldStatusOldStartType的旧值“ stopped”和“ Manual”

MachineName  : DCVPIM108
Name         : MSSQLServerOLAPService
Status       : Running
StartType    : Automatic
OldStatus    : Running
OldStartType : Automatic

那是为什么?

2 个答案:

答案 0 :(得分:1)

我想您想要的是将同一对象向下传递到多个管道。我没有使用-PipeLineVariable很多,但是看起来它只是为$ _创建一个更好的别名。如果您需要在管道中推送特定的内容,我想您需要对自定义对象或哈希表使用写输出。下面是一个虚拟示例,向下推并修改hastable:

$services = "xagt" , "xbgm" , "XblGameSave"
$list = new-object System.Collections.ArrayList

$serv | foreach { 

    $svc =  Get-Service $_ ; Write-Output @{Name = $svc.Name; Stat=$svc.Status}

 } | foreach {$_.SomeNewItem = "new stuff"; $list.Add($_)}

但是在您的情况下,一个管道可能就足够了。尝试类似的事情:

Import-CSV .\SSAS_services.csv | foreach  { 
  $old = Get-Service $_.Service;
  Set-Service -Name $_.Service -Status Running
  $new = Get-Service $_.Service;
  $data = $_.MachineName, $_.Service, $old.Status, $new.Status -join ","
  Write-Host $data
  $data >> Log.txt

  }

答案 1 :(得分:1)

-PipelineVariable / -pv通用参数仅适用:

    单个管道中的
  • 在同一管道的后段中的脚本块中的

由于您是在ForEach-Object脚本块内 nested 的管道中使用它,因此 outer 管道中的命令无法使用它。 / p>

但是,我建议重组您的命令,以使您不再需要Get-Service的管道变量。

  • -PipelineVariable $csvRowImport-Csv一起使用,因此即使在嵌套管道中,也可以更轻松地引用它(替代方法是在ForEach-Object脚本块的开头为$csvRow = $_)。

  • 然后,将
  • $svc声明为-OutVariable,以便在调用Set-Service进行更改之前捕获原始服务状态。

  • 获取服务,设置服务的启动类型以及使用其他信息丰富CSV行对象,现在都发生在ForEach-Object脚本块中。

Import-CSV .\SSAS_services.csv -PipelineVariable csvRow | ForEach-Object {
  Get-Service -Name $csvRow.Service -ComputerName $csvRow.Server -OutVariable svc |
    Set-Service -Status $csvRow.Task -StartupType $csvRow.'Startup Type'
  $csvRow | Select-Object MachineName, Name, Status, StartType,
                          @{n='OldStatus';e={$svc.Status}},
                          @{n='OldStartType';e={$svc.StartType}}
} | Tee-object -FilePath '.\ChangeServices_LOG.txt'