powershell service if scripts - powershell

I am trying to right a script to check if a services is running on one of our servers if the services are running just write an event log, but if the services are stopped run another script outside of this script. I am running to issues with verifying if the services are running. I am sure it's simple but I am not that proficient in if statements. Any help is much appreciated.
# Service Status
$Service='Spooler'
# Check service
((get-service $service).Status -eq 'Running')
$Service2='VMTools'
((get-service $service2).Status -eq 'Running')
Execute Restarting Script if Stopped Service
{
if ($service.Status -eq 'Stopped')
$service = False
{
elseif($Service2.Status -eq 'Stopped')
"$service2 = False"
}
else {
Z:\SeviceRestart.ps1
} } Write-EventLog -LogName "Service_TestScript" -Source
"Service_TestScript" -EventId 1 -Message "Verified $service ,
$service2 are running"
My script now
Service Status
$Service='Ipswitch SSH Server'
$Service2='Ipswitch WS_FTP Server'
function RestartServiceIfStopped([string]$service) {
$serviceStatus = (Get-Service $service).Status
if ($serviceStatus -eq 'Stopped'){
Start-Service -displayname $service
Write-Host "Started $service"
}
elseif ($serviceStatus -eq 'Running'){
Write-Host "Service $service is running"
}
Write-EventLog -logname application -source MyApplication -eventid 1 -message "$service is running" }
$hostname = 'FTP02'
$smtpServer = '####'
function SendMailMessageIFStopped([string]$service)
{
$serviceStatus = (Get-Service $service).Status
if ($serviceStatus -eq 'Stopped'){
Send-MailMessage -To '####' -Subject "Restarting Printspooler Service on $hostname" -Body "This is an automated message
to confirm that the $Service , $Service2 service on $hostname
is about to be restarted as part of failure, after recieving this message please check system to confirm." -From
test#test.com -SmtpServer $smtpServer } }
RestartServiceIfStopped "Ipswitch SSH Server"
RestartServiceIfStopped 'Ipswitch WS_FTP Server'
Write-EventLog -Entrytype Warning -LogName "Service_TestScript"
-Source "Service_TestScript" -EventId 1 -Message "Verified $service , $service2 are running"

You can simplify your script
function RestartServiceIfStopped([string]$service)
{
$serviceStatus = (Get-Service $service).Status
if ($serviceStatus -eq 'Stopped'){
Start-Service -displayname $service
Write-Host "Started $service"
}
elseif ($serviceStatus -eq 'Running'){
Write-Host "Service $service is running"
}
#Write-EventLog -logname application -source MyApplication -eventid 1 -message "$service is running"
}
RestartServiceIfStopped "Spooler"
For EventLog, you will have to create an event source using New-EventLog cmdlet (once per host).

Figured it out I had to put the Send-MailMessage under the first IF-statement
Thank you for your help Punit Ganshani MVP
Service Status
$Service='Print Spooler' $Service2='VMTools' $hostname = 'FTP02'
$smtpServer = '****'
function RestartServiceIfStopped([string]$service) {
$serviceStatus = (Get-Service $service).Status
if ($serviceStatus -eq 'Stopped'){
Start-Service -displayname $service
Write-Host "Started $service"
Send-MailMessage -To 'test#test.com,' -Subject
"Restarting $service and $service2 Service on $hostname" -Body "This
is an automated message to confirm that the $Service , $Service2
service on $hostname is about to be restarted as part of failure,
after recieving this message please check system to confirm." -From
-SmtpServer $smtpServer
}
elseif ($serviceStatus -eq 'Running'){
Write-Host "Service $service is running"
}
{
$serviceStatus = (Get-Service $service2).Status
if ($serviceStatus -eq 'Stopped'){
Start-Service -displayname $service2
Write-Host "Started $service2"
}
elseif ($serviceStatus -eq 'Running'){
Write-Host "Service $service2 is running"
} } } RestartServiceIfStopped "Print Spooler" RestartServiceIfStopped 'VMTools'
Write-EventLog -Entrytype Warning -LogName "Service_TestScript"
-Source "Service_TestScript" -EventId 1 -Message "Verified $service , $service2 are running"

Related

Print Timestamp of Stop and Start Services into .txt file

I want timestamp when services is stopped/restarted then output to file. The file will become as attached and send to support.
I cannot output to file as my below query seems got error.
$hostname = $env:computername
$smtpServer = 'smtpServer'
$from = "from"
$recipients = 'recipients'
$Subject = "Services Restarted Successfully on $hostname $ipv4"
$body = "This mail confirms that the service on $hostname $ipv4 is now running."
$ipv4 = (Test-Connection -ComputerName $env:computername -count 1).ipv4address.IPAddressToString
$natip = Invoke-WebRequest ifconfig.me
$timestamp = (Get-Date)
$output = D:\Testing\Restart.txt
$attachment = $output
$service = 'Apache'
Stop service
Stop-Service -name $service -Verbose
do {
Start-sleep -s 5 | Write-Output "$timestamp Services is stopped" | Out-file $output
}
until ((get-service $service).Status -eq 'Stopped')
Start service
start-Service -name $service -Verbose
do {
Start-sleep -s 5 | Write-Output "$timestamp Services is restarted" | Out-file $output
}
until ((get-service $service).Status -eq 'Running')
Send confirmation that service has restarted successfully
Start-Sleep -s 5
Send-MailMessage -To $recipients -Subject $Subject -Body $body ((gsv Apache) | out-string) -From $from -SmtpServer $smtpServer -Attachments $attachment
As stated in above comments, change your code to
Stop-Service -name $service -Verbose
do {
Start-sleep -s 5
Write-Output "$timestamp Services is stopped" | Out-file $output
} until ((get-service $service).Status -eq 'Stopped')
Actually your Start-Sleep cmledt calls output is sent to the pipeline ( Start-sleep - s 5 |...). My guess is that Start-sleep doesn't returns anything, so nothing is send to the pipeline. Based on that Write-Output is not called.
Antoher guess: Assignment to $output fails since your path is not a string, Powershell may interpret the assignment in command mode. Change it to:
$output = "D:\Testing\Restart.txt"

Stop and start service in-order on a remote server

I want to write a script to check 4 service on a server if they have status running when we stop them by order and start them on the other hand with delay.
First service must check that it is running and then start with others therefore we use delay.
$serverlist = Get-Content “.\server.txt”
$servicename4 = "Orbit Utveckling Consul"
$servicename3 = "Orbit Utveckling Identity"
$servicename2 = "Orbit Utveckling Service"
$servicename1 = "Orbit Utveckling Integration"
$delay = 60 # Ange i sekunder.
foreach ($server in $serverlist) {
$getservicestatus1 = Get-Service -Name $servicename1 -ComputerName $server
if ($getservicestatus1 -eq "Running") {
Set-Service -Name $servicename1 -ComputerName $server -Status stopped
Write-Host "$server $servicename1 Stoppat!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan $servicename2 stoppar..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus2 = (Get-Service -Name $servicename2 -ComputerName $server).status
if ($getservicestatus2 -eq "Running") {
Set-Service -Name $servicename2 -ComputerName $server -Status stopped
Write-Host "$server $servicename2 Stoppat!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server stoppar..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus3 = (Get-Service -Name $servicename3 -ComputerName $server).status
if ($getservicestatus3 -eq "Running") {
Set-Service -Name $servicename3 -ComputerName $server -Status stopped
Write-Host "$server $servicename3 Stoppat!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server stoppar..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus4 = (Get-Service -Name $servicename4 -ComputerName $server).status
if ($getservicestatus4 -eq "Running") {
Set-Service -Name $servicename4 -ComputerName $server -Status stopped
Write-Host "$server $servicename4 Stoppat!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server stoppar..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
}
# Filen startar tjänsten Drift_Cosmic på varje IX3a i txt-filen.
# Det görs med en delay på ett antal sekunder mellan varje start.
# Detta är en testfil tills dess att en riktig testkörning
# har gjorts i Drift.
Write-Host "$servicename4, $servicename3, $servicename2, $servicename1 startas med $delay sekunders mellanrum."
foreach ($server in $serverlist) {
# Skriv ut status på tjänsten i passande färg.
$getservicestatus4 = (Get-Service -Name $servicename4 -ComputerName $server).status
if ($getservicestatus4 -eq "Stopped") {
Set-Service -Name $servicename4 -ComputerName $server -Status Running
Write-Host "$server $servicename4 Startad!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server startas..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus3 = (Get-Service -Name $servicename3 -ComputerName $server).status
if ($getservicestatus3 -eq "Stopped") {
Set-Service -Name $servicename3 -ComputerName $server -Status Running
Write-Host "$server $servicename3 Startad!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server startas..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus2 = (Get-Service -Name $servicename2 -ComputerName $server).status
if ($getservicestatus2 -eq "Stopped") {
Set-Service -Name $servicename2 -ComputerName $server -Status Running
Write-Host "$server $servicename2 Startad!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server startas..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
$getservicestatus1 = (Get-Service -Name $servicename1 -ComputerName $server).status
if ($getservicestatus1 -eq "Stopped") {
Set-Service -Name $servicename1 -ComputerName $server -Status Running
Write-Host "$server $servicename1 Startad!" -ForegroundColor Green
Write-Host "Väntar i $delay sekunder innan nästa server startas..."
$nexttime = (Get-Date).AddSeconds($delay)
Write-Host "Nästa start sker $nexttime"
Start-Sleep -Seconds $delay
}
}
Write-Host "." -ForegroundColor DarkBlue
Read-Host "Tryck ENTER för att avsluta"
You can configure service dependencies so that a service will only start/stop once its dependent services are also started/stopped.
Once you've done this you only need to stop service1 and Windows will deal with stopping the services dependencies... in order of their dependents.
You can see other services that have dependencies in Services. For example Fax service depends on Print Spooler, which itself depends on RPC, which then depends on DCOM
If manually stopped the Fax service, you'll see the GUI stop (in order) DCOM, RPC, Spooler then Fax.
Configuring dependencies only needs to be done once (per server):
sc config "service1" depend= "service2"
sc config "service2" depend= "service3"
sc config "service3" depend= "service4"
etc...
(There's no native Powershell command for doing this to my knowledge, I've only found sc.exe and using wmi, with sc being the simpler command.)
After this is setup you would only need a small bit of code to restart all the services in order:
$serverlist = Get-Content ".\server.txt"
foreach ($server in $serverlist) {
Get-Service -Name "service1" -ComputerName $server | Restart-Service
}

Set local system as Windows service identity [duplicate]

I want to create a Windows Service using Powershell. Creating it for a given user is piece of cake. I used this function adapted from here.
function ReinstallService1 ($serviceName, $binaryPath, $login, $pass)
{
Write-Host "installing service"
# creating credentials which can be used to run my windows service
$secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($login, $secpasswd)
# creating widnows service using all provided parameters
New-Service -name $serviceName -binaryPathName $binaryPath -displayName $serviceName -startupType Automatic -credential $mycreds
Write-Host "installation completed"
}
My question is: How can I create for "Network Service" account?
If I modify New-Service line and remove credential parameter, the service is created for "Local System" account. Nearly miss.
New-Service -name $serviceName -binaryPathName $binaryPath -displayName $serviceName -startupType Automatic
I googled a lot and saw no way of indicating service account. If I try to use Credential parameter for user "NETWORK SSERVICE", I don't know what password to put and if I invent one (just in case cmdlet ignores it) it doesn't work. The error is:
New-Service : Service 'XXXX (XXXX)'
cannot be created due to the following error: The account name is
invalid or does not exist, or the password is invalid for the account
name specified
The correct name of the account is NT AUTHORITY\NETWORK SERVICE.
This is the final version of Reinstall Service for everyone's benefit, specially for Aniket.
function ReinstallService ($serviceName, $binaryPath, $description, $login, $password, $startUpType)
{
Write-Host "Trying to create service: $serviceName"
#Check Parameters
if ((Test-Path $binaryPath)-eq $false)
{
Write-Host "BinaryPath to service not found: $binaryPath"
Write-Host "Service was NOT installed."
return
}
if (("Automatic", "Manual", "Disabled") -notcontains $startUpType)
{
Write-Host "Value for startUpType parameter should be (Automatic or Manual or Disabled) and it was $startUpType"
Write-Host "Service was NOT installed."
return
}
# Verify if the service already exists, and if yes remove it first
if (Get-Service $serviceName -ErrorAction SilentlyContinue)
{
# using WMI to remove Windows service because PowerShell does not have CmdLet for this
$serviceToRemove = Get-WmiObject -Class Win32_Service -Filter "name='$serviceName'"
$serviceToRemove.delete()
Write-Host "Service removed: $serviceName"
}
# if password is empty, create a dummy one to allow have credentias for system accounts:
#NT AUTHORITY\LOCAL SERVICE
#NT AUTHORITY\NETWORK SERVICE
if ($password -eq "")
{
#$secpassword = (new-object System.Security.SecureString)
# Bug detected by #GaTechThomas
$secpasswd = (new-object System.Security.SecureString)
}
else
{
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
}
$mycreds = New-Object System.Management.Automation.PSCredential ($login, $secpasswd)
# Creating Windows Service using all provided parameters
Write-Host "Installing service: $serviceName"
New-Service -name $serviceName -binaryPathName $binaryPath -Description $description -displayName $serviceName -startupType $startUpType -credential $mycreds
Write-Host "Installation completed: $serviceName"
# Trying to start new service
Write-Host "Trying to start new service: $serviceName"
$serviceToStart = Get-WmiObject -Class Win32_Service -Filter "name='$serviceName'"
$serviceToStart.startservice()
Write-Host "Service started: $serviceName"
#SmokeTest
Write-Host "Waiting 5 seconds to give time service to start..."
Start-Sleep -s 5
$SmokeTestService = Get-Service -Name $serviceName
if ($SmokeTestService.Status -ne "Running")
{
Write-Host "Smoke test: FAILED. (SERVICE FAILED TO START)"
Throw "Smoke test: FAILED. (SERVICE FAILED TO START)"
}
else
{
Write-Host "Smoke test: OK."
}
}
You could get a cred of network service straightforward like this:
$login = "NT AUTHORITY\NETWORK SERVICE"
#### #just set a dummy psw since it's just used to get credentials
$psw = "dummy"
$scuritypsw = ConvertTo-SecureString $psw -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential($login, $scuritypsw)
#### #then you can use the cred to new a windows service
$serviceName = "Test"
$binaryPath = "C:\Test\Test.exe"
New-Service -name $serviceName -binaryPathName $binaryPath -displayName $serviceName -startupType Automatic -credential $mycreds
Get-WmiObject is deprecated now. However, PowerShell now has built in cmdlets to work with services. Here is the updated version of ReinstallService from Oscar Foley's answer tweaked accordingly along with convenient default values and wrappers to start and stop a service:
# https://stackoverflow.com/questions/35064964/powershell-script-to-check-if-service-is-started-if-not-then-start-it
function TryStopService([string] $serviceName)
{
Write-Host "Attempting to stop service: $serviceName..."
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if($service)
{
if ($service.Status -ne 'Running')
{
Write-Host " Service: $serviceName is not running."
}
else
{
Stop-Service -name $serviceName
Write-Host " Stopped service: $serviceName."
}
}
else
{
Write-Host " Service: $serviceName is not found."
}
}
function UninstallService([string] $serviceName)
{
Write-Host "Attempting to uninstall service: $serviceName..."
if (Get-Service $serviceName -ErrorAction SilentlyContinue)
{
Remove-Service -Name $serviceName
Write-Host " Uninstalled service: $serviceName."
}
else
{
Write-Host " Service: $serviceName is not found."
}
}
function StartSertice([string] $serviceName)
{
Write-Host "Attempting to start service: $serviceName..."
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if($service)
{
if ($service.Status -eq 'Running')
{
Write-Host " Service: $serviceName is already running."
return
}
}
# Trying to start new service.
Write-Host " Trying to start new service: $serviceName."
Start-Service -Name $serviceName
#Check that service has started.
Write-Host " Waiting 5 seconds to give service time to start..."
Start-Sleep -s 5
$testService = Get-Service -Name $serviceName
if ($testService.Status -ne "Running")
{
[string] $errMessage = " Failed to start service: $serviceName"
Write-Host $errMessage
Throw $errMessage
}
else
{
Write-Host " Started service: $serviceName."
}
}
function ReinstallService ([string] $serviceName, [string] $binaryPath, [string] $description = "", [string] $login = "NT AUTHORITY\NETWORK SERVICE", [string] $password = "", [string] $startUpType = "Automatic")
{
Write-Host "Attempting to reinstall service: $serviceName..."
#Check Parameters
if ((Test-Path $binaryPath)-eq $false)
{
Write-Host " BinaryPath to service was not found: $binaryPath."
Write-Host " Service was NOT installed."
return
}
if (("Automatic", "Manual", "Disabled") -notcontains $startUpType)
{
Write-Host " Value for startUpType parameter should be (Automatic or Manual or Disabled) and it was $startUpType"
Write-Host " Service was NOT installed."
return
}
TryStopService -serviceName $serviceName
UninstallService -serviceName $serviceName
# if password is empty, create a dummy one to allow having credentias for system accounts:
# NT AUTHORITY\LOCAL SERVICE
# NT AUTHORITY\NETWORK SERVICE
if ($password -eq "")
{
$secpassword = (new-object System.Security.SecureString)
}
else
{
$secpassword = ConvertTo-SecureString $password -AsPlainText -Force
}
$mycreds = New-Object System.Management.Automation.PSCredential ($login, $secpassword)
# Creating Windows Service using all provided parameters.
Write-Host "Installing service: $serviceName with user name: '$login'..."
New-Service -name $serviceName -binaryPathName $binaryPath -Description $description -displayName $serviceName -startupType $startUpType -credential $mycreds
Write-Host " Installed service: $serviceName."
# Trying to start new service.
StartSertice -serviceName $serviceName
}

Mapped drive monitoring using PowerShell 2.0

I'm writing a PowerShell 2.0 script to monitor and reconnect network drives that should be mapped. It works...mostly. Once a drive is determined to be disconnected my logon script (ptt.vbs) is run and the drives are remapped. However, after that it continues to see that particular drive letter as disconnected even though it got remapped.
while($true) {
$disconnectedDrives = #()
$mappedDrives = 'J:', 'R:', 'S:', 'W:'
foreach ($drive in $mappedDrives) {
if (-Not (Test-Path $drive)) {
$disconnectedDrives += $drive
}
}
if ($disconnectedDrives) {
Write-Host "$disconnectedDrives not mapped."
Write-Eventlog -LogName 'Windows PowerShell' -Category 3 -source PowerShell -eventID 601 -EntryType Error -message "$disconnectedDrives OFFLINE and not available."
\\dc1\NETLOGON\ptt.vbs
}
Start-Sleep 1
}
Any ideas what I'm doing wrong?
To me the mix of VBS and Powershell is suspicious.
But at least a would take a differnt way. First create a central file whch includes the network drive configuration. For example "\dc1\NETLOGON\ptt.csv" can look like this ...
J;\\srv1\shareA
R;\\srv1\shareB
S;\\srv2\shareA
W;\\srv2\shareB
This is the script ...
$Local:LogicalDiskStatus = New-Object -TypeName 'System.Collections.Generic.Dictionary[string,System.Management.ManagementObject]'
$Local:NetDrvConf_Path = "\\dc1\NETLOGON\ptt.csv"
$Local:NetDrvConf_List = #()
$Local:NetDrvConf_DrvType = [UInt32]4
$Local:WshNetworkObj = New-Object -ComObject WScript.Network
while($true) {
# adding the logical disk status to a list indexed by DeviceID
$LogicalDiskStatus.Clear()
Get-WmiObject -Class "Win32_LogicalDisk" | ForEach-Object { $LogicalDiskStatus.Add((($_.DeviceID) -replace ":"), $_) }
if (!($NetDrvConf_List.Count)) {
Try {
$NetDrvConf_List.Clear()
$NetDrvConf_List = Import-Csv -Path $NetDrvConf_Path -Delimiter ";"
}
Catch [System.Exception] {
$Local:ErrorMsg = ("Cannot load network drive configuration file `"{0}`". Error message: {1}" -f $NetDrvConf_Path, ($_.Exception.Message))
Write-Host $ErrorMsg -ForegroundColor red
Write-Eventlog -LogName "Windows PowerShell" -Category 3 -Source PowerShell -EventId 601 -EntryType Error -Message $ErrorMsg
}
}
$NetDrvConf_List | ForEach-Object {
$Local:Current_DriveLetter = ($_.Drive).ToUpper()
$Local:Current_DriveID = ("{0}:" -f $Current_DriveLetter)
$Local:Current_UNCPath = $_.UNCPath
Write-Host ("Check configuration: {0} {1}" -f $Current_DriveID, $Current_UNCPath)
# drive in use?
if ( ($LogicalDiskStatus.ContainsKey($Current_DriveLetter)) ) {
# drive is a network drive?
if (!(($LogicalDiskStatus.$Current_DriveLetter.DriveType).Equals($NetDrvConf_DrvType))) {
$Local:ErrorMsg = ("Drive `"{0}`" is already in use, but not as a network drive! The current drive type is `"{1}`" not `"4`"." -f $Current_DriveID, ($LogicalDiskStatus.$Current_DriveLetter.DriveType) )
Write-Host $ErrorMsg -ForegroundColor red
Write-Eventlog -LogName "Windows PowerShell" -Category 3 -Source PowerShell -EventId 602 -EntryType Error -Message $ErrorMsg
# drive is NOT to the expected UNC path?
} elseif (!(($LogicalDiskStatus.$Current_DriveLetter.ProviderName).Equals($Current_UNCPath))) {
Try {
Write-Host ("Network drive `"{0}`" unexpectedly connected to `"{1}`". Trying to disconnect." -f $Current_DriveID, ($LogicalDiskStatus.$Current_DriveLetter.ProviderName)) -ForegroundColor yellow
$WshNetworkObj.RemoveNetworkDrive($Current_DriveID, $true, $true)
Write-Host ("=> successfully disconnected.") -ForegroundColor green
}
Catch [System.Exception] {
$Local:ErrorMsg = ("Error disconnecting `"{0}`". Connected to `"{1}`". Error message: {2}" -f $Current_DriveID, $Current_UNCPath, ($_.Exception.InnerException) )
Write-Host $ErrorMsg -ForegroundColor red
Write-Eventlog -LogName "Windows PowerShell" -Category 3 -Source PowerShell -EventId 603 -EntryType Error -Message $ErrorMsg
}
} else {
Write-Host "=> correct connected" -ForegroundColor green
}
}
# drive is unused?
if (!(((Get-PSProvider -PSProvider FileSystem).Drives.Name).Contains($Current_DriveLetter))) {
Try {
Write-Host ("Connecting network drive `"{0}`" to `"{1}`"." -f $Current_DriveID, $Current_UNCPath) -ForegroundColor yellow
$WshNetworkObj.MapNetworkDrive($Current_DriveID, $Current_UNCPath, $true)
Write-Host ("=> successfully connected.") -ForegroundColor green
}
Catch [System.Exception] {
$Local:ErrorMsg = ("Error connecting `"{0}`" to `"{1}`". Error message: {2}" -f $Current_UNCPath, $Current_DriveID, ($_.Exception.InnerException) )
Write-Host $ErrorMsg -ForegroundColor red
Write-Eventlog -LogName "Windows PowerShell" -Category 3 -Source PowerShell -EventId 604 -EntryType Error -Message $ErrorMsg
}
}
}
Start-Sleep -Seconds 1
}

How to create a Windows Service in Powershell for "Network Service" account?

I want to create a Windows Service using Powershell. Creating it for a given user is piece of cake. I used this function adapted from here.
function ReinstallService1 ($serviceName, $binaryPath, $login, $pass)
{
Write-Host "installing service"
# creating credentials which can be used to run my windows service
$secpasswd = ConvertTo-SecureString $pass -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ($login, $secpasswd)
# creating widnows service using all provided parameters
New-Service -name $serviceName -binaryPathName $binaryPath -displayName $serviceName -startupType Automatic -credential $mycreds
Write-Host "installation completed"
}
My question is: How can I create for "Network Service" account?
If I modify New-Service line and remove credential parameter, the service is created for "Local System" account. Nearly miss.
New-Service -name $serviceName -binaryPathName $binaryPath -displayName $serviceName -startupType Automatic
I googled a lot and saw no way of indicating service account. If I try to use Credential parameter for user "NETWORK SSERVICE", I don't know what password to put and if I invent one (just in case cmdlet ignores it) it doesn't work. The error is:
New-Service : Service 'XXXX (XXXX)'
cannot be created due to the following error: The account name is
invalid or does not exist, or the password is invalid for the account
name specified
The correct name of the account is NT AUTHORITY\NETWORK SERVICE.
This is the final version of Reinstall Service for everyone's benefit, specially for Aniket.
function ReinstallService ($serviceName, $binaryPath, $description, $login, $password, $startUpType)
{
Write-Host "Trying to create service: $serviceName"
#Check Parameters
if ((Test-Path $binaryPath)-eq $false)
{
Write-Host "BinaryPath to service not found: $binaryPath"
Write-Host "Service was NOT installed."
return
}
if (("Automatic", "Manual", "Disabled") -notcontains $startUpType)
{
Write-Host "Value for startUpType parameter should be (Automatic or Manual or Disabled) and it was $startUpType"
Write-Host "Service was NOT installed."
return
}
# Verify if the service already exists, and if yes remove it first
if (Get-Service $serviceName -ErrorAction SilentlyContinue)
{
# using WMI to remove Windows service because PowerShell does not have CmdLet for this
$serviceToRemove = Get-WmiObject -Class Win32_Service -Filter "name='$serviceName'"
$serviceToRemove.delete()
Write-Host "Service removed: $serviceName"
}
# if password is empty, create a dummy one to allow have credentias for system accounts:
#NT AUTHORITY\LOCAL SERVICE
#NT AUTHORITY\NETWORK SERVICE
if ($password -eq "")
{
#$secpassword = (new-object System.Security.SecureString)
# Bug detected by #GaTechThomas
$secpasswd = (new-object System.Security.SecureString)
}
else
{
$secpasswd = ConvertTo-SecureString $password -AsPlainText -Force
}
$mycreds = New-Object System.Management.Automation.PSCredential ($login, $secpasswd)
# Creating Windows Service using all provided parameters
Write-Host "Installing service: $serviceName"
New-Service -name $serviceName -binaryPathName $binaryPath -Description $description -displayName $serviceName -startupType $startUpType -credential $mycreds
Write-Host "Installation completed: $serviceName"
# Trying to start new service
Write-Host "Trying to start new service: $serviceName"
$serviceToStart = Get-WmiObject -Class Win32_Service -Filter "name='$serviceName'"
$serviceToStart.startservice()
Write-Host "Service started: $serviceName"
#SmokeTest
Write-Host "Waiting 5 seconds to give time service to start..."
Start-Sleep -s 5
$SmokeTestService = Get-Service -Name $serviceName
if ($SmokeTestService.Status -ne "Running")
{
Write-Host "Smoke test: FAILED. (SERVICE FAILED TO START)"
Throw "Smoke test: FAILED. (SERVICE FAILED TO START)"
}
else
{
Write-Host "Smoke test: OK."
}
}
You could get a cred of network service straightforward like this:
$login = "NT AUTHORITY\NETWORK SERVICE"
#### #just set a dummy psw since it's just used to get credentials
$psw = "dummy"
$scuritypsw = ConvertTo-SecureString $psw -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential($login, $scuritypsw)
#### #then you can use the cred to new a windows service
$serviceName = "Test"
$binaryPath = "C:\Test\Test.exe"
New-Service -name $serviceName -binaryPathName $binaryPath -displayName $serviceName -startupType Automatic -credential $mycreds
Get-WmiObject is deprecated now. However, PowerShell now has built in cmdlets to work with services. Here is the updated version of ReinstallService from Oscar Foley's answer tweaked accordingly along with convenient default values and wrappers to start and stop a service:
# https://stackoverflow.com/questions/35064964/powershell-script-to-check-if-service-is-started-if-not-then-start-it
function TryStopService([string] $serviceName)
{
Write-Host "Attempting to stop service: $serviceName..."
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if($service)
{
if ($service.Status -ne 'Running')
{
Write-Host " Service: $serviceName is not running."
}
else
{
Stop-Service -name $serviceName
Write-Host " Stopped service: $serviceName."
}
}
else
{
Write-Host " Service: $serviceName is not found."
}
}
function UninstallService([string] $serviceName)
{
Write-Host "Attempting to uninstall service: $serviceName..."
if (Get-Service $serviceName -ErrorAction SilentlyContinue)
{
Remove-Service -Name $serviceName
Write-Host " Uninstalled service: $serviceName."
}
else
{
Write-Host " Service: $serviceName is not found."
}
}
function StartSertice([string] $serviceName)
{
Write-Host "Attempting to start service: $serviceName..."
$service = Get-Service -Name $serviceName -ErrorAction SilentlyContinue
if($service)
{
if ($service.Status -eq 'Running')
{
Write-Host " Service: $serviceName is already running."
return
}
}
# Trying to start new service.
Write-Host " Trying to start new service: $serviceName."
Start-Service -Name $serviceName
#Check that service has started.
Write-Host " Waiting 5 seconds to give service time to start..."
Start-Sleep -s 5
$testService = Get-Service -Name $serviceName
if ($testService.Status -ne "Running")
{
[string] $errMessage = " Failed to start service: $serviceName"
Write-Host $errMessage
Throw $errMessage
}
else
{
Write-Host " Started service: $serviceName."
}
}
function ReinstallService ([string] $serviceName, [string] $binaryPath, [string] $description = "", [string] $login = "NT AUTHORITY\NETWORK SERVICE", [string] $password = "", [string] $startUpType = "Automatic")
{
Write-Host "Attempting to reinstall service: $serviceName..."
#Check Parameters
if ((Test-Path $binaryPath)-eq $false)
{
Write-Host " BinaryPath to service was not found: $binaryPath."
Write-Host " Service was NOT installed."
return
}
if (("Automatic", "Manual", "Disabled") -notcontains $startUpType)
{
Write-Host " Value for startUpType parameter should be (Automatic or Manual or Disabled) and it was $startUpType"
Write-Host " Service was NOT installed."
return
}
TryStopService -serviceName $serviceName
UninstallService -serviceName $serviceName
# if password is empty, create a dummy one to allow having credentias for system accounts:
# NT AUTHORITY\LOCAL SERVICE
# NT AUTHORITY\NETWORK SERVICE
if ($password -eq "")
{
$secpassword = (new-object System.Security.SecureString)
}
else
{
$secpassword = ConvertTo-SecureString $password -AsPlainText -Force
}
$mycreds = New-Object System.Management.Automation.PSCredential ($login, $secpassword)
# Creating Windows Service using all provided parameters.
Write-Host "Installing service: $serviceName with user name: '$login'..."
New-Service -name $serviceName -binaryPathName $binaryPath -Description $description -displayName $serviceName -startupType $startUpType -credential $mycreds
Write-Host " Installed service: $serviceName."
# Trying to start new service.
StartSertice -serviceName $serviceName
}