Solved

powershell script error

Posted on 2016-11-15
11
62 Views
Last Modified: 2016-11-17
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
Comment
Question by:creative555
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 2
11 Comments
 
LVL 69

Expert Comment

by:Qlemo
ID: 41888778
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
 
LVL 69

Expert Comment

by:Qlemo
ID: 41888789
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
 
LVL 84

Expert Comment

by:oBdA
ID: 41888835
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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:creative555
ID: 41890634
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
 

Author Comment

by:creative555
ID: 41890654
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
 
LVL 84

Accepted Solution

by:
oBdA earned 500 total points
ID: 41890951
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
 

Author Comment

by:creative555
ID: 41891663
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
 

Author Comment

by:creative555
ID: 41891672
error1.jpg
0
 
LVL 84

Assisted Solution

by:oBdA
oBdA earned 500 total points
ID: 41891681
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
 

Author Comment

by:creative555
ID: 41891701
Thank you so much! It is working now! Perfect
0

Featured Post

Forrester Webinar: xMatters Delivers 261% ROI

Guest speaker Dean Davison, Forrester Principal Consultant, explains how a Fortune 500 communication company using xMatters found these results: Achieved a 261% ROI, Experienced $753,280 in net present value benefits over 3 years and Reduced MTTR by 91% for tier 1 incidents.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article explains how to prepare an HTML email signature template file containing dynamic placeholders for users' Azure AD data. Furthermore, it explains how to use this file to remotely set up a department-wide email signature policy in Office …
This script can help you clean up your user profile database by comparing profiles to Active Directory users in a particular OU, and removing the profiles that don't match.
The viewer will learn how to dynamically set the form action using jQuery.
In this fifth video of the Xpdf series, we discuss and demonstrate the PDFdetach utility, which is able to list and, more importantly, extract attachments that are embedded in PDF files. It does this via a command line interface, making it suitable …

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question