Solved

Create PowerShell script to restart service on remote computer as a specified user

Posted on 2014-04-29
12
2,460 Views
Last Modified: 2014-04-30
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.
0
Comment
Question by:EndTheFed
[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
  • 6
  • 5
12 Comments
 
LVL 29

Expert Comment

by:becraig
ID: 40030025
Not sure if you mean something like this:

$username = "domain\user"
$svcpasswd = read-host -assecurestring "Please Enter the password for this account"
$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.startservice()

	}
	Catch {
		Write-host "There was an error processing your request" -fore RED; 
		exit;
	}

Open in new window

0
 

Author Comment

by:EndTheFed
ID: 40030053
thanks becraig. Looks good, I'm going to give it a try!
0
 
LVL 70

Expert Comment

by:Qlemo
ID: 40030163
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.
0
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
LVL 29

Expert Comment

by:becraig
ID: 40030222
Also for me I just used the old "ntrights" exe to do this:

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

Open in new window


usually using a security group as it is best practice to segment user rights based on groups.
0
 

Author Comment

by:EndTheFed
ID: 40032155
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\Untitled1.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
0
 
LVL 29

Expert Comment

by:becraig
ID: 40032166
$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
0
 

Author Comment

by:EndTheFed
ID: 40032216
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\Untitled1.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
0
 

Author Comment

by:EndTheFed
ID: 40032239
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?
0
 
LVL 29

Accepted Solution

by:
becraig earned 500 total points
ID: 40032265
$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.startservice()

	}
	Catch {
		Write-host "There was an error processing your request" -fore RED; 
		exit;
	}
                         

Open in new window

0
 

Author Comment

by:EndTheFed
ID: 40033060
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
0
 

Author Comment

by:EndTheFed
ID: 40033109
Works perfectly.

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;
	}
 

Open in new window

0
 
LVL 29

Expert Comment

by:becraig
ID: 40033114
$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;
	}
                   

Open in new window

     

Try this I have not tested.

I was going to use (do while) but I think this might work if your service actually stops
0

Featured Post

Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

Question has a verified solution.

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

Auditing domain password hashes is a commonly overlooked but critical requirement to ensuring secure passwords practices are followed. Methods exist to extract hashes directly for a live domain however this article describes a process to extract u…
For anyone that has accidentally used newSID with Server 2008 R2 (like I did) and hasn't been able to get the server running again because you were unlucky (as I was) and had no backups - I was able to get things working by doing a Registry Hive rec…
This tutorial will walk an individual through locating and launching the BEUtility application to properly change the service account username and\or password in situation where it may be necessary or where the password has been inadvertently change…
This tutorial will walk an individual through the process of transferring the five major, necessary Active Directory Roles, commonly referred to as the FSMO roles to another domain controller. Log onto the new domain controller with a user account t…
Suggested Courses

624 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