0

How can i split my output from undesired "content" for example

Get-ChildItem Cert:\LocalMachine\CA | Where-Object Subject -Match "Windows"

i get subject looking like this

CN=Microsoft Windows Hardware Compatibility, OU=Microsoft Corporation, OU=Microsoft Windows Hardware Compatibility Intermediate CA, OU=Copy....

How can i display only content without "CN=" , "OU=" but only like this, in a one-liner:

Microsoft Windows Hardware Compatibility Microsoft Corporation Microsoft Windows Hardware Compatibility Intermediate CA

2 Answers2

2

Is this what you are after?

Clear-Host
(
    Get-ChildItem -Path 'Cert:\LocalMachine\CA' | 
    Where-Object Subject -Match 'Windows'
).Subject -replace  ',|.[A-Z]='
# Results
<#
Microsoft Windows Hardware Compatibility Microsoft Corporation Microsoft Windows Hardware Compatibility Intermediate CA Copyright (c) 1997 Microsoft 
Corp.
#>
postanote
  • 15,138
  • 2
  • 14
  • 25
  • Yes it seems to be working just as i wanted. I will try it out as an variable and see what happens when i test the code in a computerarray and see what happens. But works like a charm, thank you! – Paddingtonbear Sep 04 '22 at 06:25
1

You're looking to extract the field values from a DN (Distinguished Name).

postanote's answer somewhat does that, but, due to returning a single string with spaces as the separator, the boundaries between the field values are lost.

If you want to retrieve the field values as an array of strings, use the regex::Matches() .NET method; you can convert the array to a single-line representation with a separator of choice using -join later:

# Outputs the field values as an *array*
[regex]::Matches(
  (Get-ChildItem Cert:\LocalMachine\CA | Where-Object Subject -Match Windows).Subject, 
  '(?<==)[^,]+'
).Value

A simplified example, using -join with a custom separator:

[regex]::Matches(
  'CN=common name, OU=org unit 1, OU=org unit 2', 
  '(?<==)[^,]+'
).Value -join '|'

Verbatim output:

common name|org unit 1|org unit 2

If separator-based single-line output is the only goal, you can simplify to a single -replace operation (same output as above):

(
  'CN=common name, OU=org unit 1, OU=org unit 2' -replace 
    '(?:^|, )[a-z]+=', '|'
).Substring(1)

Caveat: like postanote's answer, this assumes that no field value contains escaped , or = characters in the form of \, or \=.
A more complex regex would be required to account for that, such as shown in this answer.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    ''mklement0', agreed, and I originally started down this path (still using a simple replace ***-replace '.[A-Z]=' -replace ',\s', '|'***) but changed to what I provided, specifically what the OP showed as their desired output. – postanote Sep 04 '22 at 21:07
  • Understood, @postanote. My aim was to point out the limitation of a single-line representation based on spaces as the separators, and to provide a solution that overcomes this limitation. I see that the solution in your previous comment would also work to produce a single-line representation with a custom separator with the specific DN (Distinguished Name) at hand, which only has _two-character_ field names. Generally speaking, however, this is not true of all field names - see [the docs](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/ldap/distinguished-names). – mklement0 Sep 05 '22 at 00:19
  • 1
    @postanote, you could overcome the latter limitation with something like `('CN=common name, OU=org unit 1, OU=org unit 2' -replace '(?:^|, )[a-z]+=', '|').Substring(1)`, though the caveat with respect to not handling _escaped_ characters correctly still applies. – mklement0 Sep 05 '22 at 00:25
  • 1
    Agreed adn copy that, regarding the escape char thing. – postanote Sep 05 '22 at 04:34