Invoke-Command on multiple servers

Ask your PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
This topic is 9 years and 5 months old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked
User avatar
Jan.Kaspar
Posts: 5
Last visit: Thu Dec 01, 2016 2:08 am

Invoke-Command on multiple servers

Post by Jan.Kaspar »

Hello guys,

I am trying to write script for deployment agent to selected servers.

App is just directory with some files and exe. Exe support paramater for install as service. I can run invoke command for selected computer and it works. But I wanna have progress bar and run it on all computer in paralel.

Without progress bar I can simplz do it using invoke-command:

Code: Select all

$session = new-pssession -computername $SelectedItems -Name "DeployCMK"
Invoke-command -session $session -scriptblock {...Loong script... }

I was thinking about solution:

Code: Select all

$session = new-pssession -computername $SelectedItems -Name "DeployCMK"

$result = Invoke-command -session $session -scriptblock {...part 1... Return $bool}
statusbar1.value = 10

If ($result) {
Invoke-command -session $session -scriptblock {...part 2...}
statusbar1.value = 20

Invoke-command -session $session -scriptblock {...part 4...}
statusbar1.value = 30

Invoke-command -session $session -scriptblock {...part 5...}
statusbar1.value = 40
}
But I have a problem with part one, there is check if app is in actual version. If it is true. Stop proccesing installation / update. Problem is that if I run it against one server it work. If i select multiple servers and at least one of them is actual ($result = $true) it stop all others..

How can i do it correctly?

Thanks

Caspi
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Invoke-Command on multiple servers

Post by jvierra »

Sorry but it is very hard to understand what you are asking. You are missing most of the code that does your process. What you have posted does not explain what is happening.

The undefined scriptblocks are not much help here.

Rethink your question and try to ask it with more useful information.
User avatar
Jan.Kaspar
Posts: 5
Last visit: Thu Dec 01, 2016 2:08 am

Re: Invoke-Command on multiple servers

Post by Jan.Kaspar »

I have a script to deploy monitoring agent to servers. This script is executed at startup by GPO.

Code: Select all

# Service Stop
Start-Transcript -Path C:\Windows\cmk.txt
#-------------------------------------------------
#  Functions
#-------------------------------------------------
function CompareFileVersion	{
Param(
	[Parameter(Mandatory=$true)]
	[String]$PrimaryFile,$SecondaryFile
	)		
Try {
	$Primary = Get-FileHash $PrimaryFile -Algorithm SHA256 -ErrorAction Stop | Select Hash -ExpandProperty Hash
	}
Catch {
    Write-Host "Error: Cannot get primary file Hash!"
    Exit
	}

Try {
	$Secondary = Get-FileHash $SecondaryFile -Algorithm SHA256 | select Hash -ExpandProperty Hash
	}
Catch {
	$Secondary = $null
	}

If($Primary -eq $Secondary) {
		Return $True		
	}
	Else {
		Return $False
	}
}
#------------------------------------------------
# Stop agent
#------------------------------------------------
If(!(CompareFileVersion \\monitor\AGENT\CMK\check_mk_agent.exe C:\Windows\CMK\check_mk_agent.exe)){
    Write-Verbose "Newer version of agent was found. Updating..." -Verbose
    If (Get-Service -Name "check_mk_agent" -ErrorAction SilentlyContinue) {
        If((get-service -Name "check_mk_agent").Status -ne "Stopped"){
            stop-service -Name "check_mk_agent" -Force -Verbose         
			$loop = 0
			While((get-service -Name "check_mk_agent").Status -ne "Stopped"){
                Start-sleep -s 2
				$loop++
        		If($loop -eq 10) {
            		Write-Verbose "Agent was not Stopped in time limit." -Verbose
					Break
        		}
            }
        }
#------------------------------------------------
#  Remove Agent
#------------------------------------------------
        Write-Verbose "Removing Agent..." -Verbose
        Start-Process C:\Windows\CMK\check_mk_agent.exe -ArgumentList remove -Verbose   
        $exist = $true
		$loop = 0
        While ($exist -eq $true){
            If (!(Get-Service -Name "check_mk_agent" -ErrorAction 'Ignore')) {      
        	    $exist = $false
			    Write-Verbose "Removing service..." -Verbose
    	    }
			Start-Sleep -Seconds 2
			$loop++
        	If($loop -eq 10) {
            	Write-Verbose "Agent was not removed in time limit." -Verbose
				Break
        	}
        } 
    }
#-------------------------------------------------
#  Install agent
#-------------------------------------------------
    Copy-Item "\\monitor\AGENT\CMK" "C:\Windows" -Recurse -Force -Filter * -Verbose  
    Start-Process C:\Windows\CMK\check_mk_agent.exe -ArgumentList install -Verbose
    Write-Verbose "Instaling Agent..." -Verbose
    $exist = $false
    $loop = 0
    While($exist -eq $false) {
        If(Get-Service -Name "check_mk_agent" -ErrorAction Ignore) { 
            $exist = $true
			Write-Verbose "Installing service..." -Verbose
        }
        Start-Sleep -Seconds 2
        $loop++
        If($loop -eq 10)
        {
            Write-Verbose "Agent was not installed in time limit." -Verbose
			Break
        }
    }
#-------------------------------------------------
#  Start Agent
#-------------------------------------------------
    Write-Verbose "Staring Agent..." -Verbose
    Start-Service -Name check_mk_agent -Verbose
    $loop = 0
    While ((get-service -Name "check_mk_agent").status -eq "Stopped") {
        Start-Sleep -Seconds 2
        $loop++
        If($loop -eq 10)
        {
            Write-Verbose "Agent was not started in time limit." -Verbose
			Break
        }
	}
	Write-Verbose "Finish" -Verbose
}
Else{
	Write-Verbose "Agent is up to date." -Verbose	
}
Stop-Transcript

This works correctly.

I want to execute this script to update agent without restart server remotely. So I use:

Code: Select all

$SelectedItems = $lstServers1.SelectedItems
$session = new-pssession -computername $SelectedItems -Name "DeployCMK"

Invoke-command -session $session -scriptblock { Code Above }
This is also OK.

I wanna to get probgress bar that will indicate phase of deployment:

stop agent seciton 10%
copy file section 20%
remove section 30% etc.

But i dont know how, because of remote execution. I tryed to split up scrip to multiple parts. As it is in first post.

But problem is first part if I run script on multiple servers at time. In first part there is check if agent is up to date using filehash. If agent is up to date update will be skipped. If run script on multiple servers and one of them is up to date, it skip all of them.

This is hard to explain.

SOlution can be use of:

Code: Select all

foreach ($server in $SelectedItems)
{
   $session = new-pssession -computername $SelectedItems -Name "DeployCMK"
   Invoke-command -session $session -scriptblock { Code Above }

}
But I will aplly on 100 servers, it will spend a lot of time.

Jan
jvierra
Posts: 15439
Last visit: Tue Nov 21, 2023 6:37 pm
Answers: 30
Has voted: 4 times
Been upvoted: 33 times

Re: Invoke-Command on multiple servers

Post by jvierra »

What you want is a workflow. You cannot use a progress bar remotely. You can split the script but that seems foolish.

Look into workflows or jobs. They can be monitored for progress and will run in parallel. Invoke-Command wwill not run in parallel unless we use the AsJob parameter.

help Invoke-Command -par AsJob

Output from the jobs can be polled and used to track progress.

Get-Job | Receive-Job

This will retrieve message returned from the remote script.

Workflow gives as a more robust and flexible way to run a multithreaded process against multiple targets. It also has full support for all remoting needs.
This topic is 9 years and 5 months old and has exceeded the time allowed for comments. Please begin a new topic or use the search feature to find a similar but newer topic.
Locked