UPN = Test/User@contoso.com

This topic contains 12 replies, has 6 voices, and was last updated by Profile photo of Dan Potter Dan Potter 9 months, 1 week ago.

  • Author
    Posts
  • #35666
    Profile photo of Recco Bucceri
    Recco Bucceri
    Participant

    Hey all,

    So i am in the process of cleaning up active directory at a client and part of that clean up is amending UPNs that have invalid characters in them, such as ?/#$%^&*'

    I want to right a script that searches the whole forest. Now i know that i can do this using:

    Where-object {$_.UPN -like "/" -or "'"}

    And continue the or statement until i have included all the characters i want to search for. My question is there a neater way to perform the search instead of individually listing them between -or?

  • #35671
    Profile photo of Max Kozlov
    Max Kozlov
    Participant

    read about regex

    -match '[\?/#\$%^&*'']'

  • #35677
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    Actually your first example is incorrect. That's not how the -or operator works. And the syntax for the -like operand is incorrect. You would have to use ...

    Where-object {$_.UPN -like "*/*" -or $_.UPN -like "*'*"}
    

    RegEx would definitely be a better option.

  • #35678
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    Based on Max's pattern above, you could do something along these lines.

    # Sample data for the demo, good and bad samples.
    $upnList = @'
    bob$mccoy$foo.com
    david@tango.com
    silvia#jones@foo.com
    Margo@delata.net
    jon^bon&jovey@bar.fiddlesticks.com
    Test/User@contoso.com
    bill/gates@microsoft.com
    '@ -split "`r`n"
    
    $pattern = [regex]'[\?/#\$\\%^&*'']'
    
    foreach ($upn in $upnList)
    {
        # This script assumes you are replacing bad characters with an
        # underscore.  Or you could change the replacement to '' in order
        # to just delete the bad characters.
        $upn = $upn -replace $pattern,'_'
        $upn
    }
    
  • #35696
    Profile photo of random commandline
    random commandline
    Participant

    This will replace non alpha-numeric characters from the loginname part of the UPN. You don't have to worry about selecting characters. This is fine for the English language. I used Bob's list with my example.

    # Separate UPN, remove non alpha-numeric characters
    # Display new UPN
    foreach ($upn in $upnList)
    {$m = $upn -match "(?'name'.*)(?'domain'@.*)"
        $newname = $Matches['name'] -replace '\W'
        $newupn = "{0}{1}" -f $newname,$Matches['domain']
    $newupn}
    
  • #35706
    Profile photo of Aapeli Hietikko
    Aapeli Hietikko
    Participant

    Hi all, this will be my first post on these forums so don't kill me 😉

    Mix and match from above and from my habits

    I'd take all users first to a variable, just to play with it faster and not to roll all the users again and again. Also based on my experience it's fast to play with it when it's in the memory.

    $pattern = [regex]'[\?\/\#\$\\\%\^\&\*'']'
    $ADUsers = get-aduser -fi * | select userprincipalname 
    $ADUsers.count
    $ADUsers | where {$_ -match $pattern}
    

    If you are searching something else from the UPN then I would split it from @ and look only in to the prefix part

  • #35732
    Profile photo of Recco Bucceri
    Recco Bucceri
    Participant

    Thanks so much for all the responses!

    Here is my final script. I am always open to crits on ways to better fine tune or do it differently. Always looking to learn more!

    Can the same regex principle apply to objectclass? So for example would the following work:
    $ObjectClass = [regex]'[\group\user\contact]'

    Final script__________________________________________

    $Domains = $null
    $Domain = $null
    $DomainList = $null

    $pattern = [regex]'[\?\/\#\$\\\%\^\&\*"]'

    $objForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
    $DomainList = @($objForest.Domains | Select-Object Name)
    $Domains = $DomainList | foreach {$_.Name}

    #This will search each email through all domains
    foreach($Domain in ($Domains))
    {
    Get-ADObject -filter {ObjectClass -eq "User"} -Server $domain -Properties * |
    Where-Object {$_.mail -match $pattern} |
    select DistinguishedName, userPrincipalName, mail, ObjectClass |
    Export-csv -NoTypeInformation -Delimiter ";" -Path c:\Folder\file.csv -Append

    }

  • #35735
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    I don't see where 'mail' is a property of Get-ADObject. And since that is the heart of your match statement, I can't make this work. You may want to use the EmailAddress property of the Get-ADUser cmdlet.

  • #35736
    Profile photo of Bob McCoy
    Bob McCoy
    Participant

    You really don't need to initialize you variables to $null.

    This ...

    $objForest = [System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()
    $DomainList = @($objForest.Domains | Select-Object Name)
    $Domains = $DomainList | foreach {$_.Name}
    

    ... can be reduced to this ...

    $domains = ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).Name
    
  • #35801
    Profile photo of Recco Bucceri
    Recco Bucceri
    Participant

    Awesome thanks bob, appreciate all the help!

    As far as the email attribute:

    Get-ADObject -filter {ObjectClass -eq "User"} -Server $domain -Properties * |
    Where-Object {$_.mail -match $pattern}

    I search for all properties and then single it out in the where-object {$_.Mail). I probably could change -properties * to -properties Mail.

  • #35809
    Profile photo of Dan Potter
    Dan Potter
    Participant

    $re = "[a-z0-9!#\$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#\$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?"

    $user = (get-aduser someone).userprincipalname

    ([regex]::MAtch($user, $re, "IgnoreCase ")).success

  • #35810
    Profile photo of Bob McCoy
    Bob McCoy
    Participant
    $user = (get-aduser someone).userprincipalname
    

    This assumes that the UPN is the same as the email address, which is not universally the case.

  • #35817
    Profile photo of Dan Potter
    Dan Potter
    Participant

    oops. try this.

    '^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$'

You must be logged in to reply to this topic.