Problem: Install Monitoring agent on a machine remotely, or if possible on many machines.
Started like this
$server = "server01" $Package = "NSClient++-0.3.9-Win32.msi" $Path = "\\fileserver\nsclient" Copy-Item "$Path\$Package" -Destination \\$server\c$\windows\temp $newProc=([WMICLASS]"\\$server\root\cimv2:win32_Process").Create("Msiexec /I C:\windows\temp\$Package") If ($newProc.ReturnValue -eq 0) { Write-Output "Installation spawned on $server" } else { Write-Output "Could not start installation on $server" }
Well that works.. But just for the hard coded stuff. Would be nice to have it reusable and as a function… Let’s try this…
function Install-NSClient { Param { $server = "server01" $Package = "NSClient++-0.3.9-Win32.msi" $Path = "\\fileserver\nsclient" } Copy-Item "$Path\$Package" -Destination \\$server\c$\windows\temp $newProc=([WMICLASS]"\\$server\root\cimv2:win32_Process").Create("Msiexec /I C:\windows\temp\$Package") If ($newProc.ReturnValue -eq 0) { Write-Output "Installation spawned on $server" } else { Write-Output "Could not start installation on $server" } }
I’m still not satisfied… Let’s make it more like a Cmdlet… Let’s do this instead…
<# .SYNOPSIS Installs NSClient++ on Windows clients. .DESCRIPTION Installs NSClient++ and Copys the latest configuration file and script files to the client. .PARAMETER ComputerName Computer(s) to install NSCLient++ on. .PARAMETER Path Path to where installation media is located. Don't change this unless you know what you are doing! .PARAMETER Package64 Name of 64-bit MSI package. Don't change this unless you know what you are doing! .PARAMETER Package32 Name of 32-bit MSI package. Don't change this unless you know what you are doing! .PARAMETER Parameters Extra parameters to be sent to the MSI package. Don't change this unless you know what you are doing! .EXAMPLE Install-NSClients -ComputerName server01 Installs NSClient++ on server server01. .EXAMPLE Install-NSClients -ComputerName server01 -Verbose Installs NSClient++ on server server01 and write each step to the console window. .EXAMPLE Install-NSClients -ComputerName server01,server02 Installs NSClient++ on server server01 and server02. .EXAMPLE Install-NSClient -ComputerName (Get-Content .\servers.txt) Installs NSClient++ to all servers in the file servers.txt. #> function Install-NSClient { [CmdletBinding()] Param ( [Parameter (Mandatory=$true,ValueFromPipeLineByPropertyName=$true)] [string[]]$ComputerName, [string]$Path="\\fileserver\NSClient", [string]$Package64="NSClient++-0.3.9-x64.msi", [string]$Package32="NSClient++-0.3.9-Win32.msi", [string]$Parameters="/quiet /norestart" ) Process { foreach ( $server in $ComputerName ) { Write-Verbose "Server: $server" Write-Verbose "Check OS Architecture" If (Test-Path "\\$server\c$\Program Files (x86)") { Write-Verbose "Will use 64-bit package" $Package = $Package64 } else { Write-Verbose "Will use 32-bit package" $Package = $Package32 } Write-Verbose "Copy install media locally" Copy-Item "$Path\$Package" -Destination \\$server\c$\windows\temp Write-Verbose "Start installation" $newProc=([WMICLASS]"\\$server\root\cimv2:win32_Process").Create("Msiexec /I C:\windows\temp\$Package") If ($newProc.ReturnValue -eq 0) { Write-Verbose "Wait for Service to be created" While (!(Get-service -ComputerName $server nsclientpp -ErrorAction SilentlyContinue )){} Write-Verbose "Service have been created" Write-Verbose "Push Configuration to the server" Set-NSClientSettings -ComputerName $server -Verbose:$VerbosePreference Write-Verbose "Installation Completed" } else { Write-Error "Could not start installation on $Server, error code $newProc.ReturnValue" } } } }
Now we have a function that takes input from the pipeline, can use -Verbose, it checks to see if it’s 32 or 64-bit and it also implements an endless loop if installation fails after it have been spawned 🙂
While (!(Get-service -ComputerName $server nsclientpp -ErrorAction SilentlyContinue )){}
That line will never end if the installation fails, maybe a timer of some sort could be used, like, while service not created OR timer not elapsed, do nothing…