EndTheFed
asked on
Create PowerShell script to restart service on remote computer as a specified user
I have 3 users who are not Admins or Domain Admins (and cannot be made into Admins)
These 3 users need to be able to restart a specific service on one of our servers from a shortcut on their desktop (clients are Win 7 Pro x64).
The script needs to be able to specify which user it's connecting as to restart the service so I can tell the date/time/user by looking at the logs on the server. I have already created 3 faux admin users for the scripts to use (server is Win 2008 R2)
I looked all over EE for such a script and wasn't able to find one, I apologize if this was previously answered and I missed it.
These 3 users need to be able to restart a specific service on one of our servers from a shortcut on their desktop (clients are Win 7 Pro x64).
The script needs to be able to specify which user it's connecting as to restart the service so I can tell the date/time/user by looking at the logs on the server. I have already created 3 faux admin users for the scripts to use (server is Win 2008 R2)
I looked all over EE for such a script and wasn't able to find one, I apologize if this was previously answered and I missed it.
ASKER
thanks becraig. Looks good, I'm going to give it a try!
There is some left-over stuff not required in that code. You can remove lines 3 and 4.
BTW, you can change the privileges to start a specific service with subinacl, which might be a better idea than having to use specific admin accounts allowing too much.
BTW, you can change the privileges to start a specific service with subinacl, which might be a better idea than having to use specific admin accounts allowing too much.
Also for me I just used the old "ntrights" exe to do this:
example:
usually using a security group as it is best practice to segment user rights based on groups.
example:
invoke-command -computername $server -scriptblock {
param($SGroup=$SGroup)
c:\temp\ntrights -u $SGroup +r "SeServiceLogonRight"
#Delete ntrights
del c:\temp\ntrights.exe
} -Argumentlist $SGroup
usually using a security group as it is best practice to segment user rights based on groups.
ASKER
It seems to be failing on the '-Filter "Name=$servname" portion.
I'm using the telnet service to test with. I've tried using the normal name, actual service name, and the executable name, it fails just the same with any of them (Telnet, TlntSvr, and TlntSvr.exe)
Get-WmiObject : Invalid query "select * from Win32_Service where Name=telnet"
At C:\Users\admin\Desktop\Unt itled1.ps1 :11 char:14
+ $service = Get-WmiObject -Class Win32_Service -ComputerName $server -Credentia ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException, Microsoft. PowerShell .Commands. GetWmiObje
ctCommand
There was an error processing your request
I'm using the telnet service to test with. I've tried using the normal name, actual service name, and the executable name, it fails just the same with any of them (Telnet, TlntSvr, and TlntSvr.exe)
Get-WmiObject : Invalid query "select * from Win32_Service where Name=telnet"
At C:\Users\admin\Desktop\Unt
+ $service = Get-WmiObject -Class Win32_Service -ComputerName $server -Credentia ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,
ctCommand
There was an error processing your request
$servname = "service name" has to be a VALID service name.
If you are unsure of the correct name for the service, simply fire up services.msc and look for the service in question:
Double click on the service and copy the value from:
Service name: xxxx
If you are unsure of the correct name for the service, simply fire up services.msc and look for the service in question:
Double click on the service and copy the value from:
Service name: xxxx
ASKER
Ok, so then it's "TlntSvr". That's what it's listed as in services.msc, Properties, Service name: . Unfortunately I still get the same error. Shouldn't the '*' after select read 'TlntSvr' ?
Get-WmiObject : Invalid query "select * from Win32_Service where Name=TlntSvr"
At C:\Users\admin\Desktop\Unt itled1.ps1 :11 char:14
+ $service = Get-WmiObject -Class Win32_Service -ComputerName $server -Credentia ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~~~~ ~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException, Microsoft. PowerShell .Commands. GetWmiO
bjectCommand
There was an error processing your request
Get-WmiObject : Invalid query "select * from Win32_Service where Name=TlntSvr"
At C:\Users\admin\Desktop\Unt
+ $service = Get-WmiObject -Class Win32_Service -ComputerName $server -Credentia ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-WmiObject], ManagementException
+ FullyQualifiedErrorId : GetWMIManagementException,
bjectCommand
There was an error processing your request
ASKER
oh.. it needs double quotes. "Name= $xxx" and the $servname both have to be in quotes. It works like this:
-Filter "Name='$servname'"
So now it is able to restart the service successfully however it pops up and prompts me for a password. Any way to fix that since the password is included in the script?
-Filter "Name='$servname'"
So now it is able to restart the service successfully however it pops up and prompts me for a password. Any way to fix that since the password is included in the script?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Getting very close! On tiny, faster services (such as telnet) it works perfectly, however on larger services it only stops them, and they don't start again. I think the amount of time it takes them to stop is causing it to break.
Is there a way to add a 'wait' command between $service.stopservice() and $service.startservice() ?
I'm trying it with a Start-Sleep -Seconds 10 , I'll see if that helps
Is there a way to add a 'wait' command between $service.stopservice() and $service.startservice() ?
I'm trying it with a Start-Sleep -Seconds 10 , I'll see if that helps
ASKER
Works perfectly.
Thank you so much becraig for all your help!
Final code looks like this:
Thank you so much becraig for all your help!
Final code looks like this:
$username = "domain\user"
$svcpasswd = "password" | ConvertTo-SecureString -AsPlainText -Force
$servname = "service name"
$server = "Computername"
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserName , $svcpasswd
#test the credential using a wmi call
Try {
$service = Get-WmiObject -Class Win32_Service -ComputerName $server -Credential $Credential -Filter "Name='$servname'"
$service.stopservice()
Start-Sleep -Seconds 15
$service.startservice()
}
Catch {
Write-host "There was an error processing your request" -fore RED;
exit;
}
$username = "domain\user"
$svcpasswd = "password" | ConvertTo-SecureString -AsPlainText -Force
$svcpwdr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($svcpasswd)
$svcpwd = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($svcpwdr)
$servname = "service name"
$server = "Computername"
$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $UserName , $svcpasswd
#test the credential using a wmi call
Try {
$service = Get-WmiObject -Class Win32_Service -ComputerName $server -Credential $Credential -Filter "Name='$servname'"
$service.stopservice()
$service = Get-WmiObject -Class Win32_Service -ComputerName $server -Filter "Name='$servname'"
if ($service.state -eq "Stopped") {$service.startservice()}
elseif ($service.state -ne "Stopped") {start-sleep 10;$svc = $service.name; write-host "Waiting for $svc to stop ..." -fore yellow}
}
Catch {
Write-host "There was an error processing your request" -fore RED;
exit;
}
Try this I have not tested.
I was going to use (do while) but I think this might work if your service actually stops
Open in new window