Home > Enterprise >  Powershell - How to use an * as a String Filter
Powershell - How to use an * as a String Filter

Time:01-26

I need to filter out only the AD groups from the Net User command in powershell. All the AD groups begin with an * so i would like to filter out the string by displaying everything that's preceeded by an *

I get an error since '*' is a special character and cannot be used. How do i get powershell to ignore it as a special character?

I cannot use any other commands to get AD groups, so Get-AD is not an option. i only have Net user to work with.

My base script,

Net User USER /domain | Select-String '*'

I cannot use any other script than Net user to accomplish this task, even though Get-AD would be simpler, i do not have the option.

CodePudding user response:

Instead of trying to parse the output from net user USER /domain I would use what's already available in . You can get the current logged on user's Active Directory Group Membership using adsi and adsisearcher.

Here are 2 different ways of accomplishing it.

  1. By querying the user's memberof attribute:
$searcher = [adsisearcher]::new(
    [adsi] "LDAP://$env:USERDNSDOMAIN",
    [string] "(cn=$env:USERNAME)",
    [string[]] ("memberOf", "cn")
)

$searcher.FindOne().Properties['memberof'] | ForEach-Object {
    $searcher.Filter = "(distinguishedName=$_)"
    $searcher.FindOne().Properties['cn'][0]
}
  1. By querying all groups having the user as a member:
$searcher = [adsisearcher]::new(
    [adsi] "LDAP://$env:USERDNSDOMAIN",
    [string] "(cn=$env:USERNAME)",
    [string[]] ("distinguishedName", "cn")
)

$userDn = $searcher.FindOne().Properties['distinguishedName'][0]
$searcher.Filter = "(&(objectCategory=group)(member=$userDn))"
$searcher.FindAll() | ForEach-Object {
    $_.Properties['cn'][0]
}

CodePudding user response:

You can use a backslash to escape regex special characters and use ^ to specify start of string:

> @("a", "*b", "c*", "*d", "e**") | Select-String -Pattern '^\*'
*b
*d
> @("a", "*b", "c*", "*d", "e**") -match '^\*'
*b
*d

Alternatively:

> @("a", "*b", "c*", "*d", "e**") | Where { $_.StartsWith("*") }
*b
*d

CodePudding user response:

Santiago's helpful answer shows a more robust, OO solution that is much more in the spirit of PowerShell.


To answer your question as asked:

Select-String by default interprets its (positionally implied) -Pattern argument as a regex (regular expression), where * is a metacharacter.

While \-escaping regex metacharacters is possible, the direct solution is to add the -SimpleMatch switch, which causes the -Pattern argument to be interpreted as a literal (verbatim) string:

net user $someuser /domain | Select-String * -SimpleMatch

Also note that what Select-String outputs by default aren't just the matching input lines as-is, but Microsoft.PowerShell.Commands.MatchInfo objects that provide metadata for each match, with the matching line text stored in the .Line property.

While that distinction doesn't matter much for displaying results, it may for programmatic processing, so if you only want to output the text of the matching lines, add -Raw in PowerShell (Core) 7 , or pipe to | ForEach-Object Line in Windows PowerShell.

  • Related