I have this script that changes services per a csv file input
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
it works great, except for my -PipelineVariable svc
is not working as intended. if a service was "stopped" and "Manual" before being changed to "running" and "automatic", it doesnt get the old values "stopped" and "Manual" for OldStatus
and OldStartType
MachineName : DCVPIM108
Name : MSSQLServerOLAPService
Status : Running
StartType : Automatic
OldStatus : Running
OldStartType : Automatic
why is that?
I guess what you want is to pass same object down the multiple pipes. I haven't use -PipeLineVariable much, but looks like it just creating a nicer alias for $_ . If you need to push something specific down the pipeline I guess you need to use write-ouput with custom object or hashtable. Below is a dummy sample, pushing down and modifying a 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($_)}
But in your case one pipeline might be sufficient. Try something like that:
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
}
The -PipelineVariable
/ -pv
common parameter only works:
Since you're using it in a pipeline that is nested inside the ForEach-Object
script block, the commands in the outer pipeline cannot use it.
However, I suggest restructuring your command so that you don't need a pipeline variable for Get-Service
anymore. Instead,
-PipelineVariable
$csvRow
is used with Import-Csv
, so that you can more easily refer to it even in nested pipelines (the alternative would be to define the variable explicitly at the start of the ForEach-Object
script block as $csvRow = $_
).
$svc
is then declared as an -OutVariable
, so that the original service state is captured before Set-Service
is called to change it.
Getting a service, setting its startup type, and enriching the CSV-row object with additional information now all happen inside the ForEach-Object
script block.
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'
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.