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 リモート デスクトップ サービス: セッシ...'
Related
I'm trying to run the below code and get the results to an HTML email. If I just run it as is, all of the output is on one line, which is a mess. I thought I could save the foreach right to an array, but that's not working. . . Just getting a blank array. If I run it without, I get output to the screen, so I know I'm getting results.
Connect-MsolService -Credential $Credential
$customers = Get-MsolPartnerContract -All
$body = #(foreach ($customer in $customers) {
if ($customer.defaultdomainname -notlike "*Domain1*" -and $customer.defaultdomainname -notlike "*DomainABC*") {
Get-MsolUser -All -EnabledFilter EnabledOnly -TenantId $($customer.TenantId) | ? {$_.StrongAuthenticationRequirements.State -eq $null -and $_.isLicensed -eq "TRUE"} | select UserPrincipalName
}
})
I don't have an instance to play/validate with, but try it this way (use whatever code or other formatting you choose of course):
Connect-MsolService -Credential $Credential
[System.Collections.ArrayList]$body = #()
(Get-MsolPartnerContract -All) |
ForEach-Object {
if ($PSItem.defaultdomainname -notlike '*Domain1*' -and
$PSItem.defaultdomainname -notlike '*DomainABC*'
)
{
$body.Add(
(
Get-MsolUser -All -EnabledFilter EnabledOnly -TenantId $($PSItem.TenantId) |
Where-Object {
$PSItem.StrongAuthenticationRequirements.State -eq $null -and
$PSItem.isLicensed -eq 'TRUE'
}
).UserPrincipalName
)
}
}
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
}
I'm using the following in a do-until block to loop until a specified Exchange Online migration status is present:
(Get-Migrationbatch -Identity $MigrationBatchName | Where {$_.Status -like "Completed" -or "CompletedWithErrors" -or "Corrupted" -or "Failed" -or "Stopped"})
However, the above still returns a job with the status of "Syncing" and so continues the script regardless.
I've tried -match, -eq but still the same.
What am I missing?
You have to write it like this:
(Get-Migrationbatch -Identity $MigrationBatchName | Where {($_.Status -like "Completed") -or ($_.Status -like "CompletedWithErrors") -or ($_.Status -like "Corrupted") -or ($_.Status -like "Failed") -or ($_.Status -like "Stopped")})
Here's another way to do it:
$valuesToLookFor = #(
'Completed',
'CompletedWithErrors',
'Corrupted',
'Failed',
'Stopped')
(Get-Migrationbatch -Identity $MigrationBatchName |
Where-Object { $valuesToLookFor -contains $_.Status })
It would be simpler using -in operator, given that you are not using wildcards:
(Get-Migrationbatch -Identity $MigrationBatchName | Where Status -in "Completed","CompletedWithErrors","Corrupted","Failed","Stopped")
another option convert filter array to regex string...
$filter_status = #("Completed", "CompletedWithErrors","Curropted","Failed", "Stopped")
(Get-Migrationbatch -Identity $MigrationBatchName | Where Status -Match ($filter_status -Join "|")
I've got a script which goes out to computer names from a text file and then polls the services on those machines and writes the results back to a text file.
Here's what I currently have set up:
$Computers = Get-Content computername.txt
$Output = Foreach ($Computer in $Computers) {
Write-Output "`n" "Status of $Computer".ToUpper()
Get-WMIobject -Computername $Computer win32_service | Where-Object {$_.startname -ne "LocalSystem" -and $_.startname -ne "localservice" -and $_.startname -notlike "*AUTHORITY*"} | ft name, startname, startmode, state
}
$Output | Out-File ServiceReport.txt
Is there a way to run multiple sessions at once instead of processing this incrementally? IE - send the command to all the systems at once and then receive the response and record appropriately? I've looked in to Invoke-Command and a few other things but have yet to improve time, get results to write back to the file, or get those options working generally.
Get-WMIObject will multi-thread. You just need to give it more than one computer at a time to work with:
$Computers = Get-Content computername.txt
Get-WMIobject -Computername $Computers win32_service |
Where-Object {$_.startname -ne "LocalSystem" -and $_.startname -ne "localservice" -and $_.startname -notlike "*AUTHORITY*"} |
ft PSComputerName, name, startname, startmode, state |
Out-string |
Out-File ServiceReport.txt
You'll lost the ability to have that "Status of $Computer" line before each one but you can make up for it by including the computer name in the selected objects.
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
}