1

Hi I need to get a script that will do the following:

  1. Check if a service exists
  2. If the service doesn't exist run my script
  3. If the service exists do nothing

Here is what I have but it's not working for me:

    $service = Get-WmiObject -Class Win32_Service -Filter "Name='servicename'"
if($service.Status -eq $NULL)
{
$CLID = $inclid
New-Item -Path "c:\" -Name "folder" -ItemType "directory"
Invoke-WebRequest -Uri https://something.com\setup.exe -OutFile c:\folder\swibm#$CLID#101518#.exe
$installer = "swibm#$CLID#101518#.exe"
Start-Process -FilePath $installer -WorkingDirectory "C:\folder"
}
else
{
Write-Host "Client Already Installed"
}

If I run $service.Status alone I get an "OK" returned. Under this condition I would need the script to stop and run the else section. I only want this script to run if $service.Status returns nothing. Where am I going wrong here?

L04D1NG
  • 23
  • 4
  • Is this approach any good? `if(Get-Service -ea SilentlyContinue -Name servicename){"exits"}else{"nope"}` – HelpingHand Aug 08 '20 at 22:35
  • It works fine for me. You may try putting $null on the left side `If($null -eq $services.status)` – Doug Maurer Aug 08 '20 at 22:54
  • @DougMaurer Yep this fixed it! Did I miss something in the documentation? I didn't think my order was wrong....weird. – L04D1NG Aug 08 '20 at 23:37
  • 1
    As an aside: The CIM cmdlets (e.g., `Get-CimInstance`) superseded the WMI cmdlets (e.g., `Get-WmiObject`) in PowerShell v3 (released in September 2012). Therefore, the WMI cmdlets should be avoided, not least because PowerShell [Core] (version 6 and above), where all future effort will go, doesn't even _have_ them anymore. For more information, see [this answer](https://stackoverflow.com/a/54508009/45375). – mklement0 Aug 09 '20 at 01:15
  • 1
    @mklement0 Thank you I'm always looking for better ways of doing things I unfortunately have to support a very large array of devices that are not all standardized. – L04D1NG Aug 09 '20 at 12:38

2 Answers2

2

You may try putting $null on the left hand side of the comparison.

If($null -eq $services.status)

Here is a nice write up discussing it

Doug Maurer
  • 8,090
  • 3
  • 12
  • 13
2

Simpler way to check if service exists:

if( Get-WmiObject -Class Win32_Service -Filter "Name='servicename'" ) {
    # Service exists
}
else {
    # Service doesn't exist
}

... or use the Get-Service cmdlet:

if( Get-Service -ErrorAction SilentlyContinue -Name servicename ) {
    # Service exists
}
else {
    # Service doesn't exist
}
zett42
  • 25,437
  • 3
  • 35
  • 72
  • Thank you I've updated to use `Get-Service` this is much cleaner. Do you know if this method would be considered best practice as in reference to the above poster saying I should be using `Get-CimInstance` ? – L04D1NG Aug 09 '20 at 12:36
  • Also I'm I right in that `if( Get-Service -ErrorAction SilentlyContinue -Name servicename )` is looking to see if the service exists and if true it will preform the `if` statement otherwise if the service doesn't exist it would prefom the `else` statement? – L04D1NG Aug 09 '20 at 12:46
  • 1
    @L04D1NG The approach in this answer takes advantage of PowerShell's implicit to-Boolean conversions; a non-primitive object such as what `Get-WmiObject` and `Get-Service` return is implicitly `$true`, whereas the _absence_ of output is implicitly `$false`. This shorthand approach is very convenient and works robustly in this case, but, generally speaking, there are pitfalls: see the bottom section of [this answer](https://stackoverflow.com/a/53108138/45375) for a summary of the rules. – mklement0 Aug 09 '20 at 13:40
  • @L04D1NG I think `Get-Service` could be considered "best practice", because it is a built-in PowerShell cmdlet, specifically made for this task. This makes your code cleaner and propably also has better, more specific error handling. – zett42 Aug 10 '20 at 19:44