
For some time I’ve been coding in Powershell.
This post is intendent as my little cheat sheet.
Multiline Code
When writing Powershell code this string ` could be your friend when nicely formatting the code
#this is one long oneliner which stretches over my right window
Get-service | Where-Object { $_.Status -ne "Running" -and $_.StartType -eq "Automatic" -and $_.Name } | Select-Object Name, Status, StartType, DisplayName | ForEach-Object { "$($_.DisplayName)-$($_.Status)-$($_.StartType)-$($_.Name)`r`n" }
#When I want to nicely format my code into something more practical I add `
Get-service | Where-Object { $_.Status -ne "Running" -and $_.StartType -eq "Automatic" -and $_.Name } `
| Select-Object Name, Status, StartType, DisplayName `
| ForEach-Object { "$($_.DisplayName)-$($_.Status)-$($_.StartType)-$($_.Name)`r`n" }
Get-EventLog – Parsing messages
We have some event logging on servers Event Log. Sometimes I have to go through them and generate some sort of report. In this situations I’m using regex to parse message text.
I have an Event log with this kind of message
$EXAMPLE = “Included system: SytemTEST
Description: This is the default description
TicketCreated: Ticket101″
From this kind of string, I would like to extract just text SytemTEST,This is the default description,Ticket101
For this I could use array specific values, but problem with this is, what if Description field is multiline string.
$EXAMPLE = "Included system: SytemTEST
Description: This is the default description
TicketCreated: Ticket101"
$EXAMPLE.Split("`n")[0]
$EXAMPLE.Split("`n")[1]
$EXAMPLE.Split("`n")[2]
Output:
Included system: SytemTEST
Description: This is the default description
TicketCreated: Ticket101
$EXAMPLE = "Included system: SytemTEST
Description: This is the default description
I have this multiline
TicketCreated: Ticket101"
$EXAMPLE.Split("`n")[0]
$EXAMPLE.Split("`n")[1]
$EXAMPLE.Split("`n")[2]
WrongOutput:
Included system: SytemTEST
Description: This is the default description
I have this multiline
$EXAMPLE = "Included system: SytemTEST
Description: This is the default description
I have this multiline
TicketCreated: Ticket101"
([regex]::matches($EXAMPLE,'Included system: ([^/)]+)Description:').Groups[1].Value).Trim()
([regex]::matches($EXAMPLE,'Description: ([^/)]+)TicketCreated:').Groups[1].Value).Trim()
([regex]::matches($EXAMPLE,'TicketCreated: ([^/)]+)').Groups[1].Value).Trim()
Output:
SytemTEST
This is the default description
I have this multiline
Ticket101
Now, to get EventLogs for Today for some CustomLog
$Today = (Get-date).ToString("dd.MM.yyyy")
$LogName ="CustomLog"
$LogSource = "CustomSource"
$EventID = "9999"
$events = Get-EventLog -LogName $LogName -Source $LogSource -After $Today | Where-Object {$_.EventID -eq $EventID} `
|Select-Object TimeGenerated,ReplacementStrings,"Date","Includedsystem","Description","TicketCreated"| `
ForEach-Object {
New-Object PSObject -Property @{
"Includedsystem" = ([regex]::matches($_.ReplacementStrings,'Included system: ([^/)]+)Description:').Groups[1].Value).Trim()
"Description" = ([regex]::matches($_.ReplacementStrings,'Description: ([^/)]+)TicketCreated:').Groups[1].Value).Trim()
"TicketCreated" = ([regex]::matches($_.ReplacementStrings,'TicketCreated: ([^/)]+)').Groups[1].Value).Trim()
"Date" = ($_.TimeGenerated)
}
}
$events |Sort-Object Date|Select-Object Date,IncludedSystem,Description,TicketCreated
Powershell modules Clobber
I have one large script, which does some things with VmWare and Windows Failover Cluster. But, these PS modules have some commands that are the same. Example Get-Cluster
When I run Get-Cluster command the default is VmWare PowerCli Get-cluster command.
But what if I want to start Get-Cluster from Windows Failover Cluster module?
Then you must specify the module
FailoverClusters\Get-Cluster
Log folder and cleanup
When working with Powershell, there is sometimes need to log some codes and actions. Sometimes you can log it to Windows Events, sometimes you can log it to log file.
$scriptLocation = "C:\CodesFolder\"
$date = $Date = get-date -Format "yyyyMMddHHmm"
#If the Log folder does not exists
$LogPath = "$($scriptLocation)\Log"
IF (!(Test-Path $LogPath)) { New-Item $LogPath -ItemType "directory"}
#And if there are logs older than 30Days
#clear logs older than
$daysTOClearLog ='30'
Get-ChildItem -Path $LogPath |Where-Object {($_.CreationTime -lt (Get-Date).AddDays(-$daysTOClearLog))} | Remove-Item |Out-file $Logpath\RemoveLog_$date.log
Connect to Exchange Remotely
When I need to check something from Exchange, and I don’t want to install local Exchange Powershell, there is a simple code with PSSession. It uses remote Exchange modules on Exchange server
$server = "Exchange.company.com"
$Connection = "http://" + $server + "/PowerShell/"
$Credentials = Get-Credential
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri $Connection -Authentication Kerberos –AllowRedirection -credential $Credentials
Import-PSSession $Session -Verbose -AllowClobber
#your code below
Get-User
#your code above
Remove-PSSession -Session $session
Good Luck