script block & parameter

hi everyone,

seeing that I do not know how to correctly post a bit of code, I do have 2 questions;

  • how to I insert my bit as code in here?
  • how do I correctly pass a parameter to a script?
I need to start a service on a remote computer as a job so it is done in the background instead of waiting for the result. her's my attempt;
$pcname = 'pcname'

$scriptBlock = {
param($pc)
$strQuery = "Select * from Win32_Service where Name='RemoteRegistry'"
$service = Get-WmiObject -Query $strQuery -Namespace root\cimv2 -ComputerName $pc
if ($service.StartMode -ne 'Automatic')
{ $service.ChangeStartMode('Automatic') }
if ($service.State -ne 'Running')
{ $service.StartService() }
}

Start-Job -ScriptBlock $ScriptBlock -ArgumentList $pcname

thank you!

You already have the code to pass arguments to the scriptblock. Get-Service returns the starttype and status of the service. Hence you don’t need to go with WMI.

$ScriptBlock = {
    Param($Name)
    $Param = @{Name = $Name}
    $Service = Get-Service @Param
    if($Service.StartType -ne 'Automatic'){$Param.StartType = 'Automatic'}
    if($Service.Status -ne 'Running'){$Param.Status = 'Running'}
    if($Param.StartType -or $Param.Status){Set-Service @Param}
}
Start-Job -ScriptBlock $ScriptBlock -ArgumentList 'ServiceName'

Here we create a hashtable with the service name then add starttype and status if required and use splating with Set-Service cmdlet to set both together.
Splating will help us to use a hashtable with key as Parameter name and value as its arguments and will be passed using ‘@’ to a cmdlet.

Targeting this to PCs with jobs is much simpler using Invoke-Command.

Invoke-Command -ComputerName Server1,Server2 -ScriptBlock $ScriptBlock -ArgumentList 'ServiceName' -AsJob

the parameter is not the service name but the pc name :slight_smile:

I’m doing something wrong because I’m unable to change the service state to running.

Actual solution is using Invoke-Command where Server1,2 is same as PCs.

[quote quote=149772]Actual solution is using Invoke-Command where Server1,2 is same as PCs.

[/quote]
well sadly it ain’t working for me.

the service’s status doesn’t change on my test computer.

thanks for trying!

You may debug this by adding some print statements in the if statements making sure it enters in neccessary if statements.

Hi Kardock,

Give this a try

$ScriptBlock = {
    $Name = 'RemoteRegistry'
    $Service = Get-Service -Name $Name
    if ($Service.StartupType -ne 'Automatic') {
        Set-Service -Name $Name -StartUpType Automatic -Passthru |Select-Object Name,StartType |Format-Table
    }
    if ($Service.Status -eq 'Stopped') {
        Start-Service $Name -Passthru |Select-Object Name,Status |Format-Table
    }
}

Invoke-Command -ComputerName pc1 -ScriptBlock $ScriptBlock -AsJob

pwshliquori