Powershell,  Zabbix

Check service version

Periodically there is a need to find out the version of the Windows service. For example, find out if the Zabbix agent is installed on the server and which version. I wrote the following function to solve this problem.

The function will take an array of computer names as input. You can use the pipeline. The function sequentially checks the computer’s name in DNS, the ability to connect remotely to the computer. Then connects to computer using cmdlet invoke-command, gets the service object and wmiobject. Please note that this is a deserialized object and we cannot use methods. However, these objects contain a lot of information that may be useful. If success, the function returns a hashtable, which contains information about the version of the executable file and service status.

function check-service-version {
param (
[Parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0,HelpMessage='Enter server name.')]
[Alias('Computername', 'Comp', 'Computer')]
[ValidateLength(1,253)]
[string[]]$hostname,

[Parameter(Mandatory=$false,ValueFromPipeline=$false,Position=1,HelpMessage="Enter sevice name.")]
[Alias('Service')]
[string]$ServiceName = 'Zabbix Agent',

[Parameter(Mandatory=$false,ValueFromPipeline=$false,Position=2,HelpMessage='Enter $true to use current user credentials.')]
[Alias('Creds')]
[pscredential]$Credentials,

[Parameter(Mandatory=$false,ValueFromPipeline=$false,Position=3,HelpMessage='Switch parameter to show progressbar.')]
[Alias('P')]
[switch]$Progressbar
)


begin {
$result = @()
$progress = $Null
$progresspercent = $Null
}
process {

$hostname | foreach {
$WsmanTest = $null
$ServiceObj = $null
$ServiceWMIObj = $null
$filepath = $null
$dirpath =  $null
$netdirpath = $null
$netverfilepath = $null
$oldzabbixagentversion = $null


$psobject = New-Object -TypeName psobject
$psobject | Add-Member -MemberType NoteProperty -Name "Name" -Value $_
$psobject | Add-Member -MemberType NoteProperty -Name "Dnsname" -Value "N/A"
$psobject | Add-Member -MemberType NoteProperty -Name "Wsman" -Value "N/A"
$psobject | Add-Member -MemberType NoteProperty -Name "Service" -Value "N/A"
$psobject | Add-Member -MemberType NoteProperty -Name "ServiceState" -Value "N/A"
$psobject | Add-Member -MemberType NoteProperty -Name "ServiceWmi" -Value "N/A"
$psobject | Add-Member -MemberType NoteProperty -Name "Filepath" -Value "N/A"
$psobject | Add-Member -MemberType NoteProperty -Name "Dirpath" -Value "N/A"
$psobject | Add-Member -MemberType NoteProperty -Name "Netdirpath" -Value "N/A"
$psobject | Add-Member -MemberType NoteProperty -Name "Netverfilepath" -Value "N/A"
$psobject | Add-Member -MemberType NoteProperty -Name "Version" -Value "N/A"
$psobject | Add-Member -MemberType NoteProperty -Name "Result" -Value "Error"

try {
$dnsname = Resolve-DnsName $_ -ErrorAction Stop
}
catch {
$dnsname = "Error " + $Error[0]
}
$psobject.dnsname = $dnsname

if ($dnsname -match "Error") {
$result += $psobject
return
}

try {
if ($Credentials) {
$WsmanTest = Test-WSMan -ComputerName $_ -Credential $Credentials -Authentication Default -ErrorAction Stop}
else {
$WsmanTest = Test-WSMan -ComputerName $_}
}
catch {
$WsmanTest = "Error " + $Error[0]
}
$psobject.wsman = $WsmanTest
if ($WsmanTest.ToString() -match "Error"){
$result += $psobject
return
}

try{
if ($Credentials) {
$ServiceObj = Invoke-Command -ComputerName $_ {Get-Service -Name $Using:ServiceName} -Credential $Credentials -Authentication Default -ErrorAction Stop}
else {
$ServiceObj = Invoke-Command -ComputerName $_ {Get-Service -Name $Using:ServiceName} -ErrorAction Stop}
}
catch {
$ServiceObj = "Error " + $Error[0]
}
$psobject.service = $ServiceObj

if ($ServiceObj -match "Error") {
$result += $psobject
return
}

$psobject.ServiceState = $ServiceObj.Status

try {
if ($Credentials) {
$ServiceWMIObj = Invoke-Command -ComputerName $_ {Get-WmiObject win32_service | Where-Object {$_.Name -like $Using:ServiceObj.Name}} -Credential $Credentials -Authentication Default -ErrorAction Stop}
else {
$ServiceWMIObj = Invoke-Command -ComputerName $_ {Get-WmiObject win32_service | Where-Object {$_.Name -like $Using:ServiceObj.Name}} -ErrorAction Stop}
}
catch {
$ServiceWMIObj = "Error " + $Error[0]
}
$psobject.ServiceWmi = $ServiceWMIObj

if ($ServiceWMIObj -match "Error") {
$result += $psobject
return
}

$filepath = (($ServicewmiObj.PathName -Split '.exe').trim('"'))[0] + ".exe"
$dirpath = $filepath | Split-Path
$netdirpath = "\\" + $comp + "\" + $dirpath.Replace(":\","$\")
$netverfilepath = "\\" + $comp + "\" + $filepath.Replace(":\","$\")

$psobject.Filepath = $filepath
$psobject.Dirpath = $dirpath
$psobject.Netdirpath = $netdirpath
$psobject.Netverfilepath = $netverfilepath

try {
if ($Credentials) {
$version = Invoke-Command -ComputerName $_ {(Get-Item $Using:filepath).VersionInfo.ProductVersion} -Credential $Credentials -Authentication Default -ErrorAction Stop}
else {
$version = Invoke-Command -ComputerName $_ {(Get-Item $Using:filepath).VersionInfo.ProductVersion} -ErrorAction Stop}
}
catch {
$version = "Error " + $Error[0]
}

$psobject.version = $version

if ($version -match "Error") {
$result += $psobject
return
}

$psobject.Result = "OK"
$result += $psobject
if ($hostname.count -gt 1 -and $Progressbar){
$progress++
$progresspercent = [Math]::Truncate(($progress / $hostname.count)*100)
write-progress -activity "Operation in Progress" -status "$progresspercent % Complete" -percentcomplete $progresspercent 
}
}

return $result

}
}

Leave a Reply