• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 100
  • Last Modified:

powershell script error

I was wondering if you have seen this error before? Perhaps you can suggest a better script that sets up specific logon account to run a specific service on multiple computers.

Thank you so much!
I downloaded this script from Powershell gallery and it fails with the error “Stop-Service : Cannot find any service with display name 'System.ServiceProcess.ServiceController'.

https://gallery.technet.microsoft.com/scriptcenter/Changing-multiple-Windows-e4df2574/view/Discussions#content


clear
# Script location
$ScriptPath = Split-Path -parent $MyInvocation.MyCommand.Definition

# New Service Account
$ServiceAccount = "testtarget\Username"  
$ServicePassword = "<Password>"

# Array of Services which should be changed, Use the real "Display Name" of each Service
$Srvs = ('Servicene Name');

#Prompt for an administartiv user name and password
$Cred = Get-Credential
 
#Read the servers listed in the server.txt file located in the script folder
$servers = Get-Content "c:\scripts\servers.txt"
foreach ($server in $servers)
      {
    # Stop, Configure and Restart of the listed Services above
         foreach ($Srv in $Srvs)
        {
        $gsrv = Get-Service -DisplayName $Srv
          Write-Host "Service $Srv on $server" -foreground "Green";
        Stop-Service -DisplayName $gsrv -Force
        Set-Service -InputObject $gsrv -StartupType Automatic
        $service = gwmi win32_service -ComputerName $server -filter "displayname='$Srv'" -Credential $cred
        $service.Change($null, $null, $null, $null, $null, $null, $ServiceAccount, $ServicePassword).ReturnValue
        # Status
        if ($service.Change().ReturnValue -eq "0")
            {
            Write-Host "Logon successfully Changed" -ForegroundColor "Green"
            }
        ELSE
            {
           Write-Host "Have a look for Status" $service.Change().ReturnValue "at https://msdn.microsoft.com/en-us/library/aa393673(v=vs.85).aspx" -ForegroundColor "Red"
            }
        Start-Service -DisplayName $Srv
        }
      }

Stop-Service : Cannot find any service with display name 'System.ServiceProcess.ServiceController'.
At line:8 char:9
+         Stop-Service -DisplayName $gsrv -Force
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (System.ServiceProcess.ServiceController:String) [Stop-Service], ServiceCommandException
    + FullyQualifiedErrorId : NoServiceFoundForGivenDisplayName,Microsoft.PowerShell.Commands.StopServiceCommand

gwmi : User credentials cannot be used for local connections
At line:10 char:20
+ ...  $service = gwmi win32_service -ComputerName $server -filter "display ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Get-WmiObject], ManagementException
    + FullyQualifiedErrorId : GetWMIManagementException,Microsoft.PowerShell.Commands.GetWmiObjectCommand

You cannot call a method on a null-valued expression.
At line:11 char:9
+         $service.Change($null, $null, $null, $null, $null, $null, $Se ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At line:13 char:13
+         if ($service.Change().ReturnValue -eq "0")
+             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Start-Service : Service 'Q Processor (QProcessor)' cannot be started due to the following error: Cannot start service
QProcessor on computer '.'.
At line:21 char:9
+         Start-Service -DisplayName $Srv
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OpenError: (System.ServiceProcess.ServiceController:ServiceController) [Start-Service], ServiceCommandException
    + FullyQualifiedErrorId : CouldNotStartService,Microsoft.PowerShell.Commands.StartServiceCommand
0
creative555
Asked:
creative555
  • 5
  • 3
  • 2
2 Solutions
 
QlemoC++ DeveloperCommented:
Stop-Service -DisplayName $gsrv -Force

Open in new window

needs to be
Stop-Service -InputObject $gsrv -Force

Open in new window

You should change the Start-Service the same way.
0
 
QlemoC++ DeveloperCommented:
Regarding the other errors, you can not run this script with your local machine as server. WMI does not allow to provide user credentials for the local machine (the reasons are complex). You've used '.', which is the local machine.
0
 
oBdACommented:
There are several blatant errors in that script; it has obviously never been tested in the version posted.
* -DisplayName instead of -Inputobject in Stop-Service
* -ComputerName argument missing for Get-Service, so the script will always start and stop the service locally
* The return value of the Change() WMI method isn't tested correctly
* Start-Service is running against a local service as well

That said, check out my former solution at https://www.experts-exchange.com/questions/28943446/PowerShell-looping-Log-on-as-a-service-script.html
It sets the "Logon as a service" right as well, if you want it to (and put ntrights.exe into the script's folder).
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
creative555Author Commented:
thank you so much! I used this script from here. One request.

I have a different service name on other servers. But all of them have one name in common.

How would you modify the script so, for example, it would update all the services with the name "*NAME*""

I tried this and it didn't work. I also tried to put two service names with commas....
$ServiceName = ("*SpecificName*");

https://www.experts-exchange.com/questions/28943446/PowerShell-looping-Log-on-as-a-service-script.html
0
 
creative555Author Commented:
Also for the second server I got this error
ComputerName : Server02
UserRight    : System.Management.Automation.RuntimeException:  Granting SeServiceLogonRight to testtarget\adms.mig.svc on
               \\SErver02OpenPolicy:   ***Error*** OpenPolicy -1073610729
GetService   :
0
 
oBdACommented:
This now accepts the service name as command line argument, so you can run it in a loop. The error with the path to ntrights.exe is fixed as well.
So create a csv file for the logon information:
"ServiceName", "ServiceAccount", "ServicePassword"
"Service1", "Domain\Account1", "TopSecret"
"Service2", "Domain\Account2", "DontTell"

Open in new window

Then you can loop it for example like this:
$ComputerList = Get-Content C:\Temp\Servers.txt
Import-Csv C:\Temp\Services.csv | % {C:\Temp\Set-ServiceLogon.ps1 -ServiceName $_.ServiceName -ServiceAccount $_.ServiceAccount -ServicePassword $_.ServicePassword -ComputerList $ComputerList}

Open in new window

[CmdletBinding()]
Param(
	[string]$ServiceName,
	[string]$ServiceAccount,
	[string]$ServicePassword,
	[string[]]$ComputerList = @($ENV:ComputerName),
	$TimeoutStop = 120,		# Seconds
	$TimeoutStart = 120		# Seconds
)
$SetUserRight = $True
$ntrights = "$(Split-Path -Path $MyInvocation.MyCommand.Path -Parent)\ntrights.exe"

$WmiReturnValueMap = @{	## 'Change method of the Win32_Service class', https://msdn.microsoft.com/en-us/library/windows/desktop/aa384901(v=vs.85).aspx
	[uint32]0 =		'The request was accepted.'
	[uint32]1 =		'The request is not supported.'
	[uint32]2 =		'The user did not have the necessary access.'
	[uint32]3 =		'The service cannot be stopped because other services that are running are dependent on it.'
	[uint32]4 =		'The requested control code is not valid, or it is unacceptable to the service.'
	[uint32]5 =		'The requested control code cannot be sent to the service because the state of the service (Win32_BaseService.State property) is equal to 0, 1, or 2.'
	[uint32]6 =		'The service has not been started.'
	[uint32]7 =		'The service did not respond to the start request in a timely fashion.'
	[uint32]8 =		'Unknown failure when starting the service.'
	[uint32]9 =		'The directory path to the service executable file was not found.'
	[uint32]10 =	'The service is already running.'
	[uint32]11 =	'The database to add a new service is locked.'
	[uint32]12 =	'A dependency this service relies on has been removed from the system.'
	[uint32]13 =	'The service failed to find the service needed from a dependent service.'
	[uint32]14 =	'The service has been disabled from the system.'
	[uint32]15 =	'The service does not have the correct authentication to run on the system.'
	[uint32]16 =	'This service is being removed from the system.'
	[uint32]17 =	'The service has no execution thread.'
	[uint32]18 =	'The service has circular dependencies when it starts.'
	[uint32]19 =	'A service is running under the same name.'
	[uint32]20 =	'The service name has invalid characters.'
	[uint32]21 =	'Invalid parameters have been passed to the service.'
	[uint32]22 =	'The account under which this service runs is either invalid or lacks the permissions to run the service.'
	[uint32]23 =	'The service exists in the database of services available from the system.'
	[uint32]24 =	'The service is currently paused in the system.'
}
$ProgressCount = 0
ForEach ($ComputerName In $ComputerList) {
	Write-Progress -Activity "[$($ProgressCount)/$($ComputerList.Count)] Changing service account for '$($ServiceName)' to $($ServiceAccount)'" -Status $ComputerName -PercentComplete (100 * $ProgressCount / $ComputerList.Count)
	$ProgressCount += 1
	$Return = "" | Select-Object -Property 'ComputerName', 'ServiceName', 'UserRight', 'GetService', 'Change', 'Stop', 'Start'
	$Return.ComputerName = $ComputerName
	$Return.ServiceName = $ServiceName
	Try {
		$Step = 'UserRight'
		If ($SetUserRight) {
			$Output = & $ntrights -m "\\$($ComputerName)" -u $ServiceAccount.Trim('.\') +r SeServiceLogonRight 2>&1
			If ($LastExitCode -eq 0) {
				$Return.$Step = 'OK'
			} Else {
				Throw ($Output -join ' ')
			}
		} Else {
			$Return.$Step = 'SKIPPED'
		}
		$Step = 'GetService'
		If (-not ($ServiceWmi = Get-WmiObject -Class Win32_Service -Filter "Name='$($ServiceName)'" -ComputerName $ComputerName -ErrorAction Stop)) {
			Throw "Get-WmiObject -Class Win32_Service : Cannot find any service with service name '$($ServiceName)'."
		}
		$ServiceNet = Get-Service -Name $ServiceName -ComputerName $ComputerName -ErrorAction Stop
		$Return.$Step = 'OK'
		$Step = 'Change'
		$ChangeResult = $ServiceWmi.Change($null, $null, $null, $null, $null, $null, $ServiceAccount, $ServicePassword)
		If ($ChangeResult.ReturnValue -eq 0) {
			$Return.$Step = 'OK'
			$Step = 'Stop'
			If ($ServiceNet.Status -eq 'Running') {
				$ServiceNet.Stop()
			}
			$ServiceNet.WaitForStatus('Stopped', [Timespan]::FromSeconds($TimeoutStop))
			$Return.$Step = 'OK'
			$Step = 'Start'
			$ServiceNet.Start()
			$ServiceNet.WaitForStatus('Running', [Timespan]::FromSeconds($TimeoutStart))
			$Return.$Step = 'OK'
		} Else {
			$Return.$Step = "$($ChangeResult.ReturnValue): $($WmiReturnValueMap[$ChangeResult.ReturnValue])"
		}
	} Catch {
		$Return.$Step = $_.Exception
	} Finally {
		$Return
	}
}
Write-Progress -Activity "Done" -Completed 

Open in new window


The error on the second server is probably a permissions issue; make sure you run it from an elevated prompt and with administrative permissions on the machines. I ran it successfully remotely against W2k12R2.
1
 
creative555Author Commented:
Do I need to change this line: string[]$ComputerList = @($ENV:ComputerName),




[CmdletBinding()]
Param(
      [string]$ServiceName,
      [string]$ServiceAccount,
      [string]$ServicePassword,
      [string[]$ComputerList = @($ENV:ComputerName),

I tried replacing it with this, but it didn't work
[CmdletBinding()]
Param(
      [string]$ServiceName,
      [string]$ServiceAccount,
      [string]$ServicePassword,
      [string[]$ComputerList = @($ComputerList),
0
 
creative555Author Commented:
error1.jpg
0
 
oBdACommented:
Save the script as I posted it, don't change anything (note that the problem with the ntrights.exe path from the other question has been fixed in the version I posted above, no need to hardcode the script path there anymore!).
It's meant as an all-purpose script, not for a hardcoded set of servers and services.
Then use it in another script just like any cmdlet (only with the path to the script you saved).
So put the two lines you inserted into a separate script
$ComputerList = ...
Import-Csv ...

Open in new window

2
 
creative555Author Commented:
Thank you so much! It is working now! Perfect
0

Featured Post

A Cyber Security RX to Protect Your Organization

Join us on December 13th for a webinar to learn how medical providers can defend against malware with a cyber security "Rx" that supports a healthy technology adoption plan for every healthcare organization.

  • 5
  • 3
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now