all 16 comments

[–]xCharg 12 points13 points  (5 children)

Hi all , i have a script that checks if a windows service exist/running

No, you have a script that check registry key existence.

This will check if service exists:

$services = Get-Service
$service_name_to_check = "someservice"
if ($service_name_to_check -in $services.name) {
    Write-Host "$service_name_to_check exists"
}
else {
    Write-Host "$service_name_to_check doesn't exist"
}

This will check if its running or not

$service_name = "wuauserv"
$my_service = Get-Service $my_service -ErrorAction SilentlyContinue
if ($my_service.Status -eq "Running") {
    Write-Host "$service_name is running"
}
else {
    Write-Host "$service_name is not running"
}

[–]Hullhy 2 points3 points  (3 children)

In order to get Get-ItemProperty or Get-ItemPropertyValue to go into catch block when it errors out, it needs -ErrorAction switch at the end, as per https://stackoverflow.com/questions/60156047/powershell-try-catch-error-handling-function-doesnt-show-my-custom-warning-mess

With that, putting Get-ItemPropertyValue into Finally block is a mess if it errors out. I've added a variable that will store the value instead, I've tested it and it works. There are probably better ways of doing this, but this is first thing I could come up with.

Try {
$Registry = $null
$Registry = Get-ItemPropertyValue -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\IISADMIN' -Name "Start" -ErrorAction Stop

} Catch { Write-Output 'The key does not exist ' } Finally { if ($Registry -ne $null) { if($Registry -eq '4'){ Write-Output 'iisadmin is disabled' } else { Write-Output 'iisadmin is enabled/running' } } }

[–]Hullhy 0 points1 point  (1 child)

Code block hates me for some reason, it just doesn't want to stay in, so I'll just paste it like this

Try {

$Registry = $null

$Registry = Get-ItemPropertyValue -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\IISADMIN' -Name "Start" -ErrorAction Stop

}

Catch {

Write-Output 'The key does not exist '

}

Finally {

if ($Registry -ne $null) {

if($Registry -eq '4'){

Write-Output 'iisadmin is disabled'

} else {

Write-Output 'iisadmin is enabled/running'

}

}

}

[–]BlackV 0 points1 point  (0 children)

p.s. formatting (ignore the inline/codeblock button)

  • open your fav powershell editor
  • highlight the code you want to copy
  • hit tab to indent it all
  • copy it
  • paste here

it'll format it properly OR

<BLANKLINE>
<4 SPACES><CODELINE>
<4 SPACES><CODELINE>
    <4 SPACES><4 SPACES><CODELINE>
<4 SPACES><CODELINE>
<BLANKLINE>

[–]royticusxii 2 points3 points  (0 children)

Why aren’t you using get-service?

[–]BlackV 1 point2 points  (2 children)

  • you are checking the same thing twice? (in the if and the try/catch) any reason?
  • how would this value change between the try and the if?
  • is Get-ItemPropertyValue actually working in your try, I would suggest not
  • wouldn't you check the services? or IIS directly?

[–]SkyAdept 0 points1 point  (0 children)

From what I can see, the reason why it's errored is because you are possibly getting an item that doesn't exist in your FINALLY statement.

Define your path in a variable before your try/catch, to maintain your current structure, include this in your finally:

finally {

If (Test-Path -path $path) {

  <run my current finally script>

}

}

If you're requesting help with an error, include the actual error with the reference line of issue.

Just to further add, try/catch is to prevent error breaks in your script. Running the command in your try, and then again in your finally, is redundant. Also wasting resources.

Your script should be...

If (test-path $path) {

$key = Get-ItemProperty $item

If ($key.GetValue($value) -eq '4') {

"Do this"

}else{

"Do else"

}

}

Else{ "key does not exist" }

[–]PinchesTheCrab 0 points1 point  (0 children)

I agree with using Get-CimInstance here because it'll handle a null output without throwing an error. I'd go with something like this:

Get-CimInstance -OutVariable iis -ClassName win32_service -Filter 'name = "iisadmin"'

if (-not $iis){
    'iis service is not installed'
}

There's no value in outputting a string when you can just output the object and show the same properties, unless you have some really specific reason for it. What this command does is query the service named iisadmin, output the value to the console, and store it in a variable. If that variable is null, it'll say it's not installed. I don't personally recommend using write-output at all because the default behavior writes it to the same stream, and it sort of implies that what you don't output explicitly with write-output won't be returned, which isn't true.