Search code examples
powershellwmiwmi-service

Powershell security get-service different results interactive vs scheduled-task


I've spent hours trying to pin down this problem. I'm running a PowerShell to verify if various services are running. I want to run it every 5 minutes from Windows Task Scheduler.

It checks services on other servers, and some on the same machine on which it is running. When I run it under task scheduler, under the same userid that I'm running interactive I get different results. Interactively, shows all the services on local machine are running. When run through task scheduler, it tells me that service is not found.

This is just a fragment of a larger program. I get the server/service names from a CSV file, then at the end it sends a nice HTML email. I added the Add-Content to create a trace file to prove this happening.

foreach ($line in $csv) {
    $reportStatus = "" 
    $ServerCount = $ServerCount + 1  

    #$Service = (get-service -Name $line.ServiceName -ComputerName $line.ServerName)
    #this is slower than above, but it gives us the processId which we can use to find out what time the service/process started 
    write-host "Verifying: " $line.ServerName $line.ServiceName 
    $myDate = Get-Date
    Add-Content D:\scripts\ServiceMonitorTrace.txt "$myDate  $($line.ServerName) $($line.ServiceName)"
    $Service = (get-wmiobject win32_service -ComputerName $line.ServerName -filter "name = '$($line.ServiceName)'")
    if ($Service -eq $null) 
    {
        $reportStatus = "Service Not Found: name = '$($line.ServiceName)'"
        $trColor = "Yellow"
        $ErrorCount = $ErrorCount + 1  
        $CriticalErrorCount = $CriticalErrorCount + 1
        $CreationDate = "NA" 
        Write-Host "----> $reportStatus " 
        Add-Content D:\scripts\ServiceMonitorTrace.txt "$myDate  $reportStatus" 
    }
  }

New Simpler Version (has exact same issue): $Service = (get-wmiobject win32_service -ComputerName "DAL-BIZ-APP01" -filter "name = 'LanManServer'") if ($Service -eq $null) { $reportStatus = "Service not found" } else { $reportStatus = "Service found" } $myDate = Get-Date Write-Host $reportStatus Add-Content D:\scripts\ServiceTestTrace.txt "$myDate $reportStatus"

Interactive Results:

10/31/2013 09:34:00  DAL-BIZ-APP01 MSDTC
10/31/2013 09:34:00  DAL-BIZ-APP01 BTSSvc$BizTalkHost_QT_Default

Scheduled Job Results:

10/31/2013 09:25:42  DAL-BIZ-APP01 MSDTC
10/31/2013 09:25:42  Service Not Found: name = 'MSDTC'
10/31/2013 09:25:42  DAL-BIZ-APP01 BTSSvc$BizTalkHost_QT_Default

I run it from a command file that contains this:

powershell -command "& 'D:\Scripts\ServerMonitor.ps1'" d:\Scripts\ServerMonitorConfig.csv

Running the command file from a non-admin command prompt window or the scheduler also seems to have different results.

New Simpler Version if someone want to try, just substitute two computer names:

$Service = (get-wmiobject win32_service -ComputerName "DAL-BIZ-APP01" -filter "name = 'LanManServer'")
if ($Service -eq $null) 
{
  $reportStatus = "Service not found" 
}
else 
{
  $reportStatus = "Service found" 
}
$myDate = Get-Date
Write-Host $reportStatus
Add-Content D:\scripts\ServiceTestTrace.txt "$myDate  DAL-BIZ-APP01 $reportStatus" 

$Service = (get-wmiobject win32_service -ComputerName "DAL-BIZ-APP02" -filter "name = 'LanManServer'")
if ($Service -eq $null) 
{
  $reportStatus = "Service not found" 
}
else 
{
  $reportStatus = "Service found" 
}
$myDate = Get-Date
Write-Host $reportStatus
Add-Content D:\scripts\ServiceTestTrace.txt "$myDate  DAL-BIZ-APP02 $reportStatus" 

Results:

10/31/2013 16:07:48  DAL-BIZ-APP01 Service found
10/31/2013 16:07:48  DAL-BIZ-APP02 Service found
10/31/2013 16:08:03  DAL-BIZ-APP01 Service not found
10/31/2013 16:08:03  DAL-BIZ-APP02 Service found

16:07:48 was from command prompt, 16:08:03 was from task scheduler.


Solution

  • I added this to code:

    if ($error -ne $null) 
    {
        Write-Host "----> $($error[0].Exception) " 
        Add-Content $TraceFilename "$myDate TRCE1 $($error[0].Exception)" 
    }
    

    Now I'm able to see the reason that was getting swallowed:

    11/13/2013 11:35:37 TRCE1 System.Management.ManagementException: Access denied at System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode) at System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext() at Microsoft.PowerShell.Commands.GetWmiObjectCommand.BeginProcessing()

    I have not yet figured out the "Access Denied", but at least I'm happy I see the true error now, i.e. the reason the result of "get-wmiobject win32_service..." was null.

    I'm following up with the "Access Denied" in a new thread here: Access Denied - get-wmiobject win32_service (Powershell)