Service Checker script issues.

  • 13 January 2021
  • 2 replies
  • 59 views

I have been having issues with a script I found and even after modifying it I am unable to make it work. Could someone take a look and see if there’s an issue that I’m missing?


The idea is to get the services before, then after a reboot. It works fine when running as system in powershell ise so I’m unsure what issue I’m running into.


I will say this is running on 2012r2 via the automox agent under remediation with exit 1.


Check Script: Exit 1


Remediation Script:


Write-Output "Beginning Scan"

[string]$myorg = "Org1"

[string]$groupname = "Group_01"




<#

$myorg = "Org1"

$groupname = "Patching_Group_01"

#>



[string]$ComputerName = "localhost"

[string]$Search = "zzzz"

[string]$Search2 = "zzzz"



$DirPath = "C:\temp\AmoxPatching\$myorg\$groupname\Services"

$DirPathCheck = Test-Path -Path $DirPath

If (!($DirPathCheck)) {

Try {

#If not present then create the dir

New-Item -ItemType Directory $DirPath -Force

}

Catch {

Write-Output "The Directory $DirPath was not created."

}

}

Set-Location -Path "C:\temp\AmoxPatching\$myorg\$groupname\Services"



$Final = @()



$hosts = $ComputerName



Foreach ($Computer in $hosts) {

$XmlNameBefore = "$Computer" + "-Before" + ".xml"

if ($ComputerName) {

$XmlNameAfter = "$Computer" + "-After" + ".Individual" + ".xml"

}

else {

$XmlNameAfter = "$Computer" + "-After" + ".xml"

}



if (!(Test-Path .\$XmlNameBefore)) {

Write-Host "(BEFORE)" -ForegroundColor Green -NoNewline

Write-Host " Connecting to $Computer..." -NoNewline



try {

get-wmiobject win32_service -ErrorAction Ignore | select SystemName, Name, DisplayName, State, StartMode | sort StartMode | Export-Clixml .\$XmlNameBefore

if ($?) { Write-Host "Success" -ForegroundColor Green }

else {

Write-Host "WMI connection failed" -ForegroundColor Red

Remove-Item .\$XmlNameBefore -recurse

}

}

Catch {

Write-Host "Access Denied" -ForegroundColor Red

}

}



elseif ((Test-Path .\$XmlNameBefore) -and !(Test-Path .\$XmlNameAfter)) {

Write-Host "(AFTER)" -ForegroundColor Yellow -NoNewline

Write-Host " Connecting to $Computer..." -NoNewline



try {

get-wmiobject win32_service -ErrorAction Ignore | select SystemName, Name, DisplayName, State, StartMode | sort StartMode | Export-Clixml .\$XmlNameAfter

if ($?) { Write-Host "Success" -ForegroundColor Green }

else {

Write-Host "FAILED" -ForegroundColor Red

Remove-Item .\$XmlNameAfter -recurse

}

}

Catch {

Write-Host "Access Denied" -ForegroundColor Red

}

}



if ((Test-Path .\$XmlNameBefore) -and (Test-Path .\$XmlNameAfter)) {



$wmi = Get-WmiObject -Class Win32_OperatingSystem -Computer $Computer

$RebootTime = $wmi.ConvertToDateTime($wmi.LastBootUpTime)

$RebootTime = $RebootTime.ToLocalTime()



$RebootDiff = ((get-date) - $RebootTime)

$RebootDiffHours = [math]::round($RebootDiff.totalHours, 1)

$RebootDiffDays = [math]::round($RebootDiff.totalDays, 1)



$XmlNameBeforeTIME = (Get-ChildItem .\$XmlNameBefore).LastWriteTime

$XmlNameAfterTIME = (Get-ChildItem .\$XmlNameAfter).LastWriteTime



[PsObject]$xmlBefore = Import-Clixml -Path ".\$XmlNameBefore"

[PsObject]$xmlAfter = Import-Clixml -Path ".\$XmlNameAfter"



$CompareBefore = @()

$CompareAfter = @()



$CompareBefore = Compare-Object $xmlBefore $xmlAfter -Property SystemName, Name, DisplayName, State, StartMode | where { $_.SideIndicator -EQ "<=" }

$CompareAfter = Compare-Object $xmlBefore $xmlAfter -Property SystemName, Name, DisplayName, State, StartMode | where { $_.SideIndicator -EQ "=>" }

if ((!$CompareBefore) -and (!$CompareAfter)) { Write-Host "► No differences found for $Computer ◄" -ForegroundColor Yellow }



$obj = @()

$obj += ForEach ($line1 in $xmlBefore) {

# Looking for all rows in the first CSV file

ForEach ($line2 in $xmlAfter) {

# Looking for all rows in the second CSV file

if ($line1.name -eq $line2.name) {

# If the same service name is found in both files

if (($line1.startmode -ne $line2.startmode) -or ($line1.state -ne $line2.state)) {

# If different



New-Object -TypeName PSObject -Property @{

SystemName = $line1.SystemName

Rebooted_Hrs = $RebootDiffHours

Name = $line1.name

DisplayName = $line1.DisplayName

StartMode_Before = $line1.startmode

StartMode_After = $line2.startmode

State_Before = $line1.state

State_After = $line2.state

}

}

}

}

} #end of Foreach



foreach ($line1a in $CompareAfter) {

$found = $false

foreach ($line1b in $CompareBefore) {

If ($line1b.DisplayName -eq $line1a.DisplayName) {

$found = $true

}

}

if ($found -eq $false) {

$obj += New-Object -TypeName PSObject -Property @{

SystemName = $line1a.SystemName

Rebooted_Hrs = $RebootDiffHours

Name = $line1a.name

DisplayName = $line1a.DisplayName

StartMode_After = $line1a.startmode

State_After = $line1a.state

StartMode_Before = '---'

State_Before = '---'

}

}

}



foreach ($line1b in $CompareBefore) {

$found = $false

foreach ($line1a in $CompareAfter) {

If ($line1a.DisplayName -eq $line1b.DisplayName) {

$found = $true

}

}

if ($found -eq $false) {

$obj += New-Object -TypeName PSObject -Property @{

SystemName = $line1b.SystemName

Rebooted_Hrs = $RebootDiffHours

Name = $line1b.name

DisplayName = $line1b.DisplayName

StartMode_Before = $line1b.startmode

State_Before = $line1b.state

StartMode_After = '---'

State_After = '---'

}

}

}



$Final += $Obj



} # End of If Test-path

} # End of Foreach $Computer



$Final2 = @()

$Final2 = $Final | sort DisplayName | Select SystemName, Rebooted_Hrs, Name, State_Before, State_After, StartMode_Before, StartMode_After, DisplayName



if ($Final2) {

If ($ComputerName) {

if (Test-Path "$($ComputerName).$($myOrg).$($PatchGroup).Report.$(Get-date -f 'yyyy.MM.dd_HH.mm.ss').html") {

remove-item "$($ComputerName).$($myOrg).$($PatchGroup).Report.$(Get-date -f 'yyyy.MM.dd_HH.mm.ss').html"

}

}

else {

If (Test-Path "$($myOrg).$($PatchGroup).Report.$(Get-date -f 'yyyy.MM.dd_HH.mm.ss').html") {

Remove-item "$($myOrg).$($PatchGroup).Report.$(Get-date -f 'yyyy.MM.dd_HH.mm.ss').html"

}

}



$head = @'

<Title>Service Compare</Title>

<style>

body

{

background-color:#FFFFFF;

font-family:Tahoma;

font-size:12pt;

}

td, th

{

border:1px solid black;

border-collapse:collapse;

}

th

{

color:white;

background-color:black;

}

table, tr, td, th { padding: 5px; margin: 0px; box-shadow: 2px 2px 1px #888}

table { margin-left:50px; }

.danger {background-color: red}

.warn {background-color: yellow}

</style>

'@



#create an xml document from the HTML fragment

[xml]$html = $Final2 | ConvertTo-Html -fragment



#check each row, skipping the TH header row

for ($i = 1; $i -le $html.table.tr.count - 1; $i++) {

$class = $html.CreateAttribute("class")

#check the value of the last column and assign a class to the row

if (($html.table.tr[$i].td[7]) -like "*$Search*") {

$class.value = "warn"

$html.table.tr[$i].Attributes.Append($class) | Out-Null

}

elseif (($html.table.tr[$i].td[7]) -like "*$Search2*") {

$class.value = "danger"

$html.table.tr[$i].Attributes.Append($class) | Out-Null

}

}



#create the final report from the innerxml which should be html code

$body = @"

<p style="LINE-HEIGHT:10px;margin-left: 60px"><b>BEFORE</b> data was collected on $XmlNameBeforeTIME</p>

<p style="LINE-HEIGHT:0px;margin-left: 60px"><b>AFTER</b> data was collected on $XmlNameAfterTIME</p>

$($html.innerxml)

"@



#put it all together

if ($ComputerName) {

ConvertTo-HTML -head $head -PostContent "<br><i>HTML Generated on $(get-date)</i>" -body $body | Out-File "$($ComputerName).$($myOrg).$($PatchGroup).Report.$(Get-date -f 'yyyy.MM.dd_HH.mm.ss').html" -Encoding ascii

}

else {

ConvertTo-HTML -head $head -PostContent "<br><i>HTML Generated on $(get-date)</i>" -body $body | Out-File "$($myOrg).$($PatchGroup).Report.$(Get-date -f 'yyyy.MM.dd_HH.mm.ss').html" -Encoding ascii

}



#$ReportPath = (Get-Item -Path ".\Report.html" -Verbose).FullName

#Invoke-Item $ReportPath

}



#else {

# if (!$Final) {write-host `n "No differences found" -ForegroundColor Yellow}

# }

2 replies

Hello driosk!


This may sound very strange, but sometimes things get funky with the " double quotes when Automox executes Powershell. I was able to get your script to work through a worklet by replacing all double quotes " with single quotes '.


Please give this a shot and let me know if the script still isn’t executing via Automox worklet.


Thanks!

Yep, that’s what it was. I was able to get it running, after brushing back up on my single quoting, it’ll need some more work to get up and running the way I want but this will do for now. Thank you.


Here’s the script, it needs some editing but it’ll probably get put into a public repo soon enough. ^_~



[string]$myorg = 'Org1'

[string]$groupname = 'Group_01'

#Single quote run

<#

$myorg = 'Org1'

$groupname = 'Patching_Group_01'

#>



[string]$ComputerName = $env:COMPUTERNAME

[string]$Search = 'zzzz'

[string]$Search2 = 'zzzz'



$DirPath = 'C:\temp\AmoxPatching\' + $myorg + '\' + $groupname + '\Services'

$DirPathCheck = Test-Path -Path $DirPath

If (!($DirPathCheck)) {

Try {

#If not present then create the dir

New-Item -ItemType Directory $DirPath -Force

}

Catch {

Write-Output 'The Directory $DirPath was not created.'

}

}

Set-Location -Path $DirPath



$Final = @()



$hosts = $ComputerName



Foreach ($Computer in $hosts) {

$XmlNameBefore = $Computer + '-Before' + '.xml'

if ($ComputerName) {

$XmlNameAfter = $Computer + '-After' + '.Individual' + '.xml'

}

else {

$XmlNameAfter = $Computer + '-After' + '.xml'

}



if (!(Test-Path $XmlNameBefore)) {

Write-Host '(BEFORE)' -ForegroundColor Green -NoNewline

Write-Host ' Connecting to'$Computer'...' -NoNewline



try {

get-wmiobject win32_service -ErrorAction Ignore | select SystemName, Name, DisplayName, State, StartMode | sort StartMode | Export-Clixml $XmlNameBefore

if ($?) { Write-Host 'Success' -ForegroundColor Green }

else {

Write-Host 'WMI connection failed' -ForegroundColor Red

Remove-Item $XmlNameBefore -recurse

}

}

Catch {

Write-Host 'Access Denied' -ForegroundColor Red

}

}



elseif ((Test-Path $XmlNameBefore) -and !(Test-Path $XmlNameAfter)) {

Write-Host '(AFTER)' -ForegroundColor Yellow -NoNewline

Write-Host ' Connecting to'$Computer'...' -NoNewline



try {

get-wmiobject win32_service -ErrorAction Ignore | select SystemName, Name, DisplayName, State, StartMode | sort StartMode | Export-Clixml $XmlNameAfter

if ($?) { Write-Host 'Success' -ForegroundColor Green }

else {

Write-Host 'FAILED' -ForegroundColor Red

Remove-Item $XmlNameAfter -recurse

}

}

Catch {

Write-Host 'Access Denied' -ForegroundColor Red

}

}



if ((Test-Path $XmlNameBefore) -and (Test-Path $XmlNameAfter)) {



$wmi = Get-WmiObject -Class Win32_OperatingSystem -Computer $Computer

$RebootTime = $wmi.ConvertToDateTime($wmi.LastBootUpTime)

$RebootTime = $RebootTime.ToLocalTime()



$RebootDiff = ((get-date) - $RebootTime)

$RebootDiffHours = [math]::round($RebootDiff.totalHours, 1)

$RebootDiffDays = [math]::round($RebootDiff.totalDays, 1)



$XmlNameBeforeTIME = (Get-ChildItem $XmlNameBefore).LastWriteTime

$XmlNameAfterTIME = (Get-ChildItem $XmlNameAfter).LastWriteTime



[PsObject]$xmlBefore = Import-Clixml -Path $XmlNameBefore

[PsObject]$xmlAfter = Import-Clixml -Path $XmlNameAfter



$CompareBefore = @()

$CompareAfter = @()



$CompareBefore = Compare-Object $xmlBefore $xmlAfter -Property SystemName, Name, DisplayName, State, StartMode | where { $_.SideIndicator -EQ '<=' }

$CompareAfter = Compare-Object $xmlBefore $xmlAfter -Property SystemName, Name, DisplayName, State, StartMode | where { $_.SideIndicator -EQ '=>' }

if ((!$CompareBefore) -and (!$CompareAfter)) { Write-Host '► No differences found for $Computer ◄' -ForegroundColor Yellow }



$obj = @()

$obj += ForEach ($line1 in $xmlBefore) {

# Looking for all rows in the first CSV file

ForEach ($line2 in $xmlAfter) {

# Looking for all rows in the second CSV file

if ($line1.name -eq $line2.name) {

# If the same service name is found in both files

if (($line1.startmode -ne $line2.startmode) -or ($line1.state -ne $line2.state)) {

# If different



New-Object -TypeName PSObject -Property @{

SystemName = $line1.SystemName

Rebooted_Hrs = $RebootDiffHours

Name = $line1.name

DisplayName = $line1.DisplayName

StartMode_Before = $line1.startmode

StartMode_After = $line2.startmode

State_Before = $line1.state

State_After = $line2.state

}

}

}

}

} #end of Foreach



foreach ($line1a in $CompareAfter) {

$found = $false

foreach ($line1b in $CompareBefore) {

If ($line1b.DisplayName -eq $line1a.DisplayName) {

$found = $true

}

}

if ($found -eq $false) {

$obj += New-Object -TypeName PSObject -Property @{

SystemName = $line1a.SystemName

Rebooted_Hrs = $RebootDiffHours

Name = $line1a.name

DisplayName = $line1a.DisplayName

StartMode_After = $line1a.startmode

State_After = $line1a.state

StartMode_Before = '---'

State_Before = '---'

}

}

}



foreach ($line1b in $CompareBefore) {

$found = $false

foreach ($line1a in $CompareAfter) {

If ($line1a.DisplayName -eq $line1b.DisplayName) {

$found = $true

}

}

if ($found -eq $false) {

$obj += New-Object -TypeName PSObject -Property @{

SystemName = $line1b.SystemName

Rebooted_Hrs = $RebootDiffHours

Name = $line1b.name

DisplayName = $line1b.DisplayName

StartMode_Before = $line1b.startmode

State_Before = $line1b.state

StartMode_After = '---'

State_After = '---'

}

}

}



$Final += $Obj



} # End of If Test-path

} # End of Foreach $Computer



$Final2 = @()

$Final2 = $Final | sort DisplayName | Select SystemName, Rebooted_Hrs, Name, State_Before, State_After, StartMode_Before, StartMode_After, DisplayName



if ($Final2) {

If ($ComputerName) {
$SingleHostReportPath = $ComputerName + '.' + $myOrg + '.' + $groupname + '.Report.' + (Get-date -f 'yyyy.MM.dd_HH.mm.ss') + '.html'
if (Test-Path $SingleHostReportPath) {

remove-item $SingleHostReportPath

}

}

else {
$MultipleHostPath = $myOrg + '.' + $groupname + '.Report.' + (Get-date -f 'yyyy.MM.dd_HH.mm.ss') + '.html'
If (Test-Path $MultipleHostPath) {

Remove-item $MultipleHostPath

}

}



$head = @'

<Title>Service Compare</Title>

<style>

body

{

background-color:#FFFFFF;

font-family:Tahoma;

font-size:12pt;

}

td, th

{

border:1px solid black;

border-collapse:collapse;

}

th

{

color:white;

background-color:black;

}

table, tr, td, th { padding: 5px; margin: 0px; box-shadow: 2px 2px 1px #888}

table { margin-left:50px; }

.danger {background-color: red}

.warn {background-color: yellow}

</style>

'@



#create an xml document from the HTML fragment

[xml]$html = $Final2 | ConvertTo-Html -fragment



#check each row, skipping the TH header row

for ($i = 1; $i -le $html.table.tr.count - 1; $i++) {

$class = $html.CreateAttribute('class')

#check the value of the last column and assign a class to the row

if (($html.table.tr[$i].td[7]) -like '*'+$Search+'*') {

$class.value = 'warn'

$html.table.tr[$i].Attributes.Append($class) | Out-Null

}

elseif (($html.table.tr[$i].td[7]) -like '*'+$Search2+'*') {

$class.value = 'danger'

$html.table.tr[$i].Attributes.Append($class) | Out-Null

}

}



#create the final report from the innerxml which should be html code

$body = @"


<p style='LINE-HEIGHT:10px;margin-left: 60px'><b>BEFORE</b> data was collected on $XmlNameBeforeTIME</p>

<p style='LINE-HEIGHT:0px;margin-left: 60px'><b>AFTER</b> data was collected on $XmlNameAfterTIME</p>

$($html.innerxml)

"@



#put it all together

if ($ComputerName) {

ConvertTo-HTML -head $head -PostContent '<br><i>HTML Generated on'(Get-Date).ToString()'</i>' -body $body | Out-File $SingleHostReportPath -Encoding ascii

}

else {

ConvertTo-HTML -head $head -PostContent '<br><i>HTML Generated on'(Get-Date).ToString()'</i>' -body $body | Out-File $MultipleHostPath -Encoding ascii

}



#$ReportPath = (Get-Item -Path '.\Report.html' -Verbose).FullName

#Invoke-Item $ReportPath

}



#else {

# if (!$Final) {write-host `n 'No differences found' -ForegroundColor Yellow}

# }

Reply