Skip to content

Instantly share code, notes, and snippets.

@mahldcat
Last active November 16, 2021 19:50
Show Gist options
  • Select an option

  • Save mahldcat/4fd31499db61230e260bd828312f5fa6 to your computer and use it in GitHub Desktop.

Select an option

Save mahldcat/4fd31499db61230e260bd828312f5fa6 to your computer and use it in GitHub Desktop.
rudimentary deployment script that will copy files to a remote server and take action on them.
<#
To make this a bit less "hard coded", Some changes I want to make:
1. Pass in a list of files to be copied over
2. Move $cred as an optional parameter
3. pass in $serverHostAction as a param [make it smart enough to handle script blocks vs local path file]
former just gets executed directly much like what this does
the latter would involve copying the file onto the box and then would run a separate invoke action against it
4. Figure out a better means to generate a final report [html doc]?
The overall workflow is sort of where I want it which is
1. Copy the local files over via "copy-item -ToSession", but they get copied to a temp folder
2. Handle configuring $serverHostAction [as called out]
3. Execute the $serverHostAction
4. Clean up- remove the temp folder
#>
param($servListPath)
function Get-Serverlist {
param($fileListPath)
[Collections.ArrayList]$serverList = @()
$serverListRaw = $null
if ($null -ne $fileListPath) {
if ((Test-Path $fileListPath)) {
$serverListRaw = Get-Content $fileListPath
}
}
return $serverList
}
function Test-JobListIsCompleted{
param($jobList)
$isCompleted=$true
$completedCt=0
foreach($job in $jobList){
if($job.State -ne "Completed"){
$isCompleted=$false
}
if($job.State -eq "Completed"){
$completedCt+=1
}
}
return $isCompleted,$completedCt
}
function Start-JobWaitLoop{
param ($jobList)
$jobsAreComplete=$true
$completedCt=0
$totalJobCt=$jobList.Count
do{
$jobsAreComplete,$completedCt = Test-JobListIsCompleted -jobList $jobList
Write-Progress "Completed $completedCt of $($jobList.Count) Jobs" -PercentComplete (($completedCt/$totalJobCt)* 100)
Start-Sleep -Milliseconds 500
}
while(-NOT $jobsAreComplete)
}
$cred = Get-Credential -Message "User that can access the remote servers"
$servList = Get-ServerList -fileListPath $servListPath
$jobs = @()
$serverHostAction = {
C:\automation\Install-ScheduledTask.ps1
$le = $LASTEXITCODE
Write-Output "Install Scheduled Task Result:$le"
Remove-Item C:\automation\Install-ScheduledTask.ps1
}
<#
This is the primary block that will be executed for each server
#>
$perServerJobAction=
{
param($serverHost,[PSCredential]$cred,$action,$filesToCopy)
$scriptBlock = [scriptblock]::Create($action)
$session = New-PSSession -ComputerName $serverHost -Credential $cred
$result = $null
if ($null -ne $session ) {
Copy-Item "C:\SourceFolder\Install-SceduledTask.ps1" C:\automation -Force -ToSession $session
$result = Invoke-Command -Session $session -ScriptBlock $scriptBlock
Remove-PSSession $session
}
return $result
}
#enqueue the jobs for each server
for($i=0;$i -lt $servList.Count; $i++){
$server= $servList[$i]
Write-Progress "Starting job for server $server" -PercentComplete (($i/$servList.Count)*100)
$j = Start-ThreadJob -ThrottleLimit 50 -ScriptBlock $perServerJobAction -Name $server -ArgumentList $server, $cred, $serverHostAction
$jobs += $j
}
#rather than using wait-job, I want something that gives some feedback
Start-JobWaitLoop -jobList $jobs
# now that all the server jobs are complete---what happened?
foreach ($job in $jobs) {
$recvJob = Receive-Job -Job $job
Write-Output "Result of Task sent to '$($job.Name)'"
foreach ($li in $recvJob) {
Write-Output $li
}
Write-Output "------------------------------------"
}
$jobs|Remove-Job
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment