powershell restart service if failed - powershell

i have the Problem that an Service is crashing whitout stopping.
This means the status is shown as running but...
However - i wrote a small (absolute Beginner(!)-)Powershell-Script to check if the app is crashed, but how do i have to continue?
If the Script finds an entry in the Eventlog it shoud stop and start the Service..
Clear-Host
$timetocheck = [DateTime]::Now.AddMinutes(-10)
$eventid = "10016"
$log = "System"
$app = "SID"
$check = "Get-WinEvent -LogName $log | Where-Object {($_.TimeCreated -ge $timetocheck) -and ($_.id -eq $eventid) -and ($_.Message -Like *$app*)}"
edit
just to clarify -
if this snippet finds nothing in the eventlog nothing should happen.
if this snippet finds at least 1 error in the eventlog the service should be stopped and restarted.
with other words - if process crashed restart else do nothing
thx

Well - now i can answer my own question.. ;)
This works:
Clear-Host
$timetocheck = [DateTime]::Now.AddMinutes(-30)
$eventid = "10016"
$log = "System"
$app = "SID"
$checking = Get-WinEvent -FilterHashtable #{Logname="$log";ID="$eventid" ;StartTime="$timetocheck"}|`
Where-Object {$_.Message -like "*$app*"}
if ($checking -like "*") {ReStart-Service -Name DistributedCOM -Force}
The Trick is the $checking -like "*". I´m not satisfied completely because this "only" checks if the Get-Winevent replys at least one sign. I would prefer to search for a string i know....
When the string to check is shorter its working with a defined string....
However - its working. And thats important. And maybe someone else needs this to.
thx to all
edit
and the first improvment....
the command Get-WinEvent -FilterHashtable #{Logname="$log";ID="$eventid" ;StartTime="$timetocheck"}| Where-Object {$_.Message -like "$app"}
takes 0,7 seconds
the command Get-WinEvent $log | Where-Object{($.TimeCreated -ge $timetocheck) -and ($.id -eq $eventid) -and ($_.Message -Like "$app")} takes 4,2 seconds
so i changed it

Try it with the following code
Clear-Host
$timetocheck = [DateTime]::Now.AddMinutes(-10)
$eventid = "10016"
$log = "System"
$app = "SID"
$check = Get-WinEvent -LogName $log | Where-Object {($_.TimeCreated -ge $timetocheck) -and ($_.id -eq $eventid) -and ($_.Message -Like "*$app*")}
if ($check -ne $null)
{
Restart-Service -Name YourService -Force
}

Related

Powershell: -or in a while loop

What is wrong with my formatting. the code runs when only one condition is in there. When I add the -or with the second condition to check it appears to not check either.
while(($TempLog.id -ne "18") -or ($TempLog.id -ne "32"))
{
$TempLog = Get-WinEvent -computername F9P8NW2-5300 -LogName 'Microsoft-Windows-RemoteAssistance/Operational'-MaxEvents 1
}
enter code here

Catching errors within powershell script

I have written a script to pull permissions from file directories so that we can audit access to folders. I just want to see what groups we have not what users so I wrote this script to pull out all group names and remove the domain name from the value so that it can then run it through a second script that corrects the AD group name for us if its incorrect at all since we ran into an issue where for some reason some were coming back with slightly different names. The problem is all the AD users named in permissions come back as errors. I want those errors to not even show up on screen is there a way to do that? As you can see I have been trying a few different ways to pipe them to a log or the -ea ignore option but it still shows the errors on screen.
$filelocationscsv = "C:\AD\Excel\File Share migration.csv"
$filelocationcsvcontents = Get-Content -LiteralPath $filelocationscsv
$AllFolders = #()
foreach ($location in $filelocationcsvcontents) {
$AllFolders += $location.Substring(0,$location.Length-1)
}
$outputfilelocation = "C:\AD\Excel\permissions.csv"
$Results = #()
$errResults = #()
Foreach ($i in $Allfolders) {
if (Test-Path $i){
Write-Host "Obtaining file permissions for $i."
$acl = (Get-Acl $i -Filter *).Access | select -ExpandProperty IdentityReference
foreach($Access in $acl) {
if ($Access.Value -notlike "BUILTIN\Administrators" -and $Access.Value -notlike "domain\Domain Admins" -and $Access.Value -notlike "CREATOR OWNER" -and $access.Value -notlike "NT AUTHORITY\SYSTEM" -and $access.Value -notlike "Everyone" -and $access.Value -notlike "BUILTIN\Users" -and $access.Value -notlike "s-1*") {
[string]$perm = $Access.Value.Split('\')[1]
if($checkgroup = Get-ADGroup $perm){
#try
#{
## if( $LASTEXITCODE -gt 0 ){
## # Handle the error here
## # This example writes to the error stream and throws a terminating error
## $errResults += $LASTEXITCODE
## Write-Error "Unable to ping server, ping returned" -EA Ignore
## }
$Properties = [ordered]#{'AD Group'=$perm}
$Results += New-Object -TypeName PSObject -Property $Properties
#}
#Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]
#{
# Write-Verbose "$perm skipped." -Verbose
# #$ErrorMessage =
# #$FailedItem = $_.Exception.ItemName
# #$errResults += $ErrorMessage + $FailedItem
#}
}
}
}
}
else {
Write-Host "$i is not accessible"
}
}
$Results | select -Property 'AD Group' -Unique | Export-Csv $outputfilelocation -NoTypeInformation
Its worth noting these errors do not stop my script from running its more of an aesthetic function as well as a learning opportunity for myself. I can use my script like it is but I would love to make it look cleaner and learn how to handle errors better.
As you
indicate you are interested in learning more about error handling, one thing I learned this week are these common Parameters for error handling and recording:
-ErrorAction
-WarningAction
-ErrorVariable
-WarningVariable
You can silence the error messages by using the parameter -ErrorAction SilentlyContinue but capture the error by using the parameter -ErrorVariable
EXAMPLE: get-adgroup -ErrorAction SilentlyContinue -ErrorVariable MyErrors
You can read and manipulate the errors by calling $MyErrors
The warnings work the same way
It might give an alternative to Try/Catch.
Thank you #pwnosh you're a genius!
I changed line 20 to
if($errResults += try {$checkgroup = Get-ADGroup $perm -ErrorAction Stop } catch {[Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]}){
This line forces the users into my CSV as well but then the second script cleans them out anyways with
$results = #()
foreach($Group in ($Groups = Import-csv C:\AD\Excel\permissions.csv)){
$groupname = $Group.'AD Group'
Write-Host "Confirming $groupname group name in AD."
$results += get-adgroup -Filter "name -like '$groupname'" -Properties * -SearchBase "dc=domain,dc=local,dc=net" | select name
}
$results | Export-Csv C:\AD\Excel\ADGroups.csv -NoTypeInformation

GetEventLog - How to have 'Message' property expanded in one line poweshell

In PowerShell I am using this cmdlet:
Get-WinEvent -LogName Microsoft-Windows-TerminalServices-LocalSessionManager/Operational | Where { ($_.ID -eq "25" -or $_.ID -eq "21") -and ($_.TimeCreated -gt [datetime]::Today.AddDays(-2))} | Select TimeCreated, Message
I need to get all information in one line. but it display the information like this.
'2020/07/07 13:12:18 リモート デスクトップ サービス: セッシ...'

Powershell script to log out users without specific process

I'm trying to write a script that will log out users which don't have specific process running in their session.
I guess the workflow should look like:
Get usernames of all the users logged in, get list of all the processes runnning on the workstation, check if X process is running for Y user, if not, then log user Y out.
So far i managed to create object with all the users currently logged in:
((quser) -replace '^>', '') -replace '\s{2,}', ',' | ConvertFrom-Csv
And list of all the processes running with usernames:
get-process -IncludeUserName
I believe foreach with if inside should do the job, but I can't quite get my head around it. I would appreciate any help.
Thanks!
edit:
$process = get-process -IncludeUserName|Where-Object{
($_.ProcessName -Like "processIneed1*") -or
($_.ProcessName -Like "processIneed2*") -or
($_.ProcessName -Like "processIneed") -or
($_.ProcessName -like 'processIneed3*') -and
($_.username -notlike '*userIwantToSkip1*') -and
($_.username -notlike '*userIwantToSkip2*')
}
$users = Get-RDUserSession | Where-Object -Property UserName -NE 'administrator'
$ActiveUsers = $users.username
foreach ($ProcUser in $process.username){
foreach ($ActiveUser in $ActiveUsers){
if ($ProcUser -like "*$ActiveUser*"){
$ActiveUsers = $ActiveUsers -notlike "*$ActiveUser*"
}
}
}
in $activeusers we are left with inactive users.
I will most likely change username to session ID and check it this way.
Next step will be logging off disconnected users.
$process = get-process -IncludeUserName|Where-Object{
($_.ProcessName -Like "processIneed1*") -or
($_.ProcessName -Like "processIneed2*") -or
($_.ProcessName -Like "processIneed") -or
($_.ProcessName -like 'processIneed3*') -and
($_.username -notlike '*userIwantToSkip1*') -and
($_.username -notlike '*userIwantToSkip2*')
}
$users = Get-RDUserSession | Where-Object -Property UserName -NE 'administrator'
$ActiveUsers = $users.username
foreach ($ProcUser in $process.username){
foreach ($ActiveUser in $ActiveUsers){
if ($ProcUser -like "*$ActiveUser*"){
$ActiveUsers = $ActiveUsers -notlike "*$ActiveUser*"
}
}
}
foreach ($inactiveusers in $ActiveUsers){
logoff $inactiveuser
}

Like in Where-Object doesn't work in PowerShell 2

I have a piece of script to do some stuff on VMs. Here it is:
$powered = Get-VM VM-TEST4-* | Where-Object { $_.PowerState -eq 'PoweredOn'
ForEach-Object -InputObject $powered { Shutdown-VMGuest -VM $_ }
# taking snapshots etc etc
# BELOW FAILS
# start up machines in order
Where-Object -Like -Property Name -InputObject $powered -Value "VM-TEST4-DB*" | ForEach-Object { if ($_ -ne $null) { Start-VM -VM $_ } }
sleep -Seconds 180
Where-Object -Like -Property Name -InputObject $powered -Value "VM-TEST4-AUX*" | ForEach-Object { if ($_ -ne $null) { Start-VM -VM $_ } }
sleep -Seconds 180
Where-Object -Like -Property Name -InputObject $powered -Value "VM-TEST4-WEB*" | ForEach-Object { if ($_ -ne $null) { Start-VM -VM $_ } }
sleep -Seconds 180
My problem with this code is that nothing gets started and I only wait. Now the idea behind it was to filter out correct server type so that DB starts earlier than AUX and WEB while $_ -ne $null check protects me if Where-Object returns no results (we have an enviroment with no AUX servers).
Any idea how to make it work properly?
The simplified where-object syntax (including the -like switch parameter) was introduced in 3.0. The -like operator works fine in the standard where-object syntax. You want something like this:
Where-Object {$_.Name -like "VM-TEST4-WEB*"}
EDIT:
The -Like parameter for where-object (which looks like an operator in the simplified syntax) was added in 3.0. The -Like operator which does string comparisons has been in PowerShell since 1.0