-PipelineVariable не работает как положено - PullRequest
0 голосов
/ 02 ноября 2018

У меня есть этот скрипт, который меняет сервисы на вход 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 не работает как положено. если служба была «остановлена» и «Вручную» перед изменением на «работающая» и «автоматическая», она не получает старые значения «остановлено» и «Вручную» для OldStatus и OldStartType

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

почему это?

Ответы [ 2 ]

0 голосов
/ 11 ноября 2018

Общий параметр -PipelineVariable / -pv работает только:

  • внутри одного конвейера.
  • в блоков сценариев в последующих сегментах того же конвейера .

Поскольку вы используете его в конвейере, который вложен внутри блока скрипта ForEach-Object, команды в external не могут его использовать.

Однако я предлагаю реструктурировать вашу команду, чтобы вам больше не требовалась переменная конвейера для Get-Service. Вместо

  • -PipelineVariable $csvRow используется с Import-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'
0 голосов
/ 02 ноября 2018

Полагаю, вам нужно передать один и тот же объект по нескольким каналам. Я не очень часто использую -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

  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...