Home > Net >  Trim string returned from Get-Package query
Trim string returned from Get-Package query

Time:02-22

I would like to request some help with extracting out some characters that are returned from a Powershell query.

The query is:

$x = Get-Package -Provider "Programs" -Name "*SomeWindowsApplication*" | Select-Object -Property FastPackageReference | Out-String

The returned format is

FastPackageReference
---------------------
hklm32\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{80F3CCC1-BBAF-45DD}

I am trying to extract (to a variable) just the value returned within the { } curly brackets

When using $x.TrimStart("hklm32") or $x.Trim("hklm32") neither appear to make any change to the string.

I've tested that it is a string using $x.GetType()

The outcome I require is a variable eg: $appvalue which when queried returns the value eg: {80F3CCC1-BBAF-45DD} including the { } brackets.

Thanks, much appreciated for any assistance.

update: a colleague of mine suggested this code, which works but it assumes the GUID is always 38 characters. (might not be a problem for this application though)

$GUID=$x.substring($x.IndexOf("{"),38)

CodePudding user response:

First of all, you need to remove | Out-String, because what you are after is the value inside property FastPackageReference

Try:

$x = Get-Package -Provider "Programs" -Name "*SomeWindowsApplication*" | Select-Object -Property FastPackageReference
$guid = ([regex]'(?i){([\dA-F-] )}$').Match($x.FastPackageReference).Groups[1].Value

or

# expand the property, so $x will only have the value, not an object with property FastPackageReference
$x = Get-Package -Provider "Programs" -Name "*SomeWindowsApplication*" | Select-Object -ExpandProperty FastPackageReference
$guid = ([regex]'(?i){([\dA-F-] )}$').Match($x).Groups[1].Value

Variable $guid now has value 80F3CCC1-BBAF-45DD

Regex details:

{               Match the character “{” literally
(               Match the regular expression below and capture its match into backreference number 1
   [\dA-F-]     Match a single character present in the list below
                A single digit 0..9
                A character in the range between “A” and “F”
                The character “-”
                Between one and unlimited times, as many times as possible, giving back as needed (greedy)
)
}               Match the character “}” literally
$               Assert position at the end of a line (at the end of the string or before a line break character)

The (?i) makes the regex work case-insensitively

CodePudding user response:

Let me complement Theo's helpful answer, which shows advanced regex techniques, with simpler alternatives, if the following assumption can be made:

Given that it looks like the substring of interest is the last \-separated token, an alternative to using a regex is to treat the string as a path and extract its leaf (file-name) component via Split-Path:

# Get the property value(s) of interest.
$x = (Get-Package -Provider Programs -Name *SomeWindowsApplication*).FastPackageReference

# -> '{80F3CCC1-BBAF-45DD}', with your sample data
Split-Path -Leaf $x 

A more concise regex-solution is possible too, using a -replace operation:

$x -replace '^[^{] '

The regex matches from the start of the input string (^) one or more characters ( ) that are not { ([^{]), i.e. everything up to but not including {; by not specifying a replacement string, the matched part is replaced with the empty string i.e. effectively removed, leaving only the {...} part at the end.

  • Related