Tinus EngOps Wiki

Logo

OpsaC - Operating as PowerShell code

Links

Home

PowerShell Blog

PowerShell Index

PowerShell Search

Additional Websites

View my GitHub Profile

View my GitHub Gists

View Tinus IT Wiki

View my Photo Website

Powershell Regex

published: August 26, 2019 author: Tinu tags: PowerShell categories: PowerShell-Basic


Table of Contents

Regex Pattern

\d digit [0-9]
\w alpha numeric [a-zA-Z0-9_]
\s whitespace character
.  any character except newline
() sub-expression
\  escape the next character

Commandlets

Get-Content   #Gets the content of the item at the specified location.
Select-String #Finds text in strings and files (grep in Linux).
Select-Object #Selects objects or object properties.
Split         #Splits an input string into an array of substrings.
Replace       #Replace characters within a string.

Dot Net

[regex]::Match   #Searches an input string for a substring that matches a regular expression pattern and returns the first occurrence as a single Match object.
[regex]::Matches #Searches an input string for all occurrences of a regular expression and returns all the matches.
[regex]::Replace #In a specified input string, replaces strings that match a regular expression pattern with a specified replacement string.
[regex]::Split   #Splits an input string into an array of substrings at the positions defined by a regular expression match.

Time offset

I found this example on the website of Kamil Procyszyn - thanks a lot for your video!

First, we get the output of the w32tm tool to extract what we want:

$time = w32tm /stripchart /computer:time.windows.com /dataonly /samples:1
$time

Output

Tracking time.windows.com [40.119.148.38:123].
Collecting 1 samples.
The current time is 17.01.2024 09:05:56.
09:05:56, +00.4413676s

To many text, I want the last line with the offset-pattern ‘\S\d+.\d+s’:

$time | Select-String -Pattern '(\S\d+\.\d+s)$'

Explanation ot the offset-pattern:

\S  = not whitespace
\d+ = one or more digits
\.  = dot (.)
s   = character 's'

Output

09:05:56, +00.4413676s

Now, I want only the value that match the pattern ‘\S\d+.\d+s’ (with a .Net-Method):

[regex]::Match($time,'(\S\d+\.\d+s)$').value

or with pipeline:

$time | Select-String -Pattern '(\S\d+\.\d+s)$' -AllMatches | `
 Select-Object -ExpandProperty matches | Select-Object -ExpandProperty value

Output

+00.4413676s

Extract from MemoryDump

From a MemoryDump I returned the Crash-date as Sun May 28 00:30:51.221 2017 (UTC + 2:00), but I need a normal DateTime-Object, so wtf should I do?

Do It with RegEx!!! Copy the string to regex101.com and test the regex-string you should use.

Code

$ContentString   = 'Sun May 28 00:30:51.221 2017 (UTC + 2:00)'
$FullRegexString = '^\w{1,3}\s\w{1,3}\s\d{1,2}\s\d{1,2}\:\d{1,2}\:\d{1,2}\.\d{1,3}\s\d{4}'

$RegexDayMonth = '^\w{1,3}\s\w{1,3}\s\d{1,2}'
$RegexYear     = '\s\d{4}\s'
$RegexTime     = '\d{1,2}\:\d{1,2}\:\d{1,2}\.\d{1,3}'

$DayMonthString   = $ContentString | Select-String -Pattern $RegexDayMonth -AllMatches | `
 Select-Object -ExpandProperty matches | Select-Object -ExpandProperty value
$YearString       = $ContentString | Select-String -Pattern $RegexYear     -AllMatches | `
 Select-Object -ExpandProperty matches | Select-Object -ExpandProperty value
$TimeString       = $ContentString | Select-String -Pattern $RegexTime     -AllMatches | `
 Select-Object -ExpandProperty matches | Select-Object -ExpandProperty value

$DateTimeString = $DayMonthString + $YearString + $TimeString -join ' '

Get-Date($DateTimeString)

Output

Sonntag, 28. Mai 2017 00:30:51

Extract from SCCM Windows Update Log

SCCM write a lot of formatted log files, but they are realy not simple to add in an object!

<#
    Troubleshooting Windows Update with SCCM
#>

$FoundUpdate     = 'Update \(Missing\)\:\D+'
$InstallStated   = 'Async installation of updates started\D+'
$InstallFinished = 'Installation of updates completed\D+'
$UpdateRegex     = '(?<=^\<\!\[LOG\[\d\.\sUpdate \(Missing\)\:\s)(.*)(?=\]LOG\]\!\>)'
$LogRegex        = '(?<=^\<\!\[LOG\[)(.*)(?=\]LOG\]\!\>)'

$TimeRegex       = '(?<=\<time=")(.*)(?=" date)'
$DateRegex       = '(?<=date=")(.*)(?=" component)'

$wulog = Get-Content -Path "C:\Windows\CCM\Logs\WUAHandler.log"

$FoundMissingUpdate = $wulog | Where {$_ -match $FoundUpdate} | ForEach {

    $_ -match $UpdateRegex | Out-Null
    $Log = $Matches[0]

    $_ -match $DateRegex | Out-Null
    $Date = $Matches[0]

    $_ -match $TimeRegex | Out-Null
    $Time = $Matches[0]

    [PSCustomObject]@{
        Message = $Log
        Date    = $Date
        Time    = $Time
    }
}

$UpdateInstallationStarted = $wulog | Where {$_ -match $InstallStated} | ForEach {

    $_ -match $LogRegex | Out-Null
    $Log = $Matches[0]

    $_ -match $DateRegex | Out-Null
    $Date = $Matches[0]

    $_ -match $TimeRegex | Out-Null
    $Time = $Matches[0]

    [PSCustomObject]@{
        Message = $Log
        Date    = $Date
        Time    = $Time
    }
}

$UpdateInstallationSucceeeded = $wulog | Where {$_ -match $InstallFinished} | ForEach {

    $_ -match $LogRegex | Out-Null
    $Log = $Matches[0]

    $_ -match $DateRegex | Out-Null
    $Date = $Matches[0]

    $_ -match $TimeRegex | Out-Null
    $Time = $Matches[0]

    [PSCustomObject]@{
        Message = $Log
        Date    = $Date
        Time    = $Time
    }
}

$InstalledUpdate = Get-HotFix | Select HotFixID,InstalledOn | sort InstalledOn | select -last 5

return @{
    LastBootTime           = (Get-CimInstance Win32_OperatingSystem).LastBootUpTime
    InstalledUpdate        = $InstalledUpdate
    MissingUpdate          = $FoundMissingUpdate
    InstallationStarted    = $UpdateInstallationStarted
    InstallationSucceeeded = $UpdateInstallationSucceeeded
}

Regex Tools

RegExr, Regular Expressions 101

See also

Powershell: The many ways to use regex on Kevin Marquette Blog.


← Previous Post [ Top ] Copyright © 2024 by tinuwalther [ Blog ] Next Post →