How To Test For Good Pattern In Attribute?

For Active Directory, I have a pretty good script written to add a new Record by copying the Attributes from an existing Record. This saves a remarkable amount of time.
Now, I would like to know how to test an Attribute, DisplayName, to see if it is good.
Our usual and good DisplayName looks like this:
Jones, Joseph - JARHD-RECON, Kansas City, MO
So it must have three commas to pass the test;
With a variable amount of Alpha, Numeric, Spaces or Special Characters, before and after the commas.

I envision something like this:

If (Good Pattern)
{Do Something}
Else
{Do Something Else}

Thank you in advance for your help.
Here is the current script that works:

Import-Module activeDirectory 
    [void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic') 
    $title = 'Get SamAccountName' 
    $msg = 'Enter SamAccountName From Regular Account' 
    $InputUser = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title) 
    $user=$InputUser.trim() 
    $XSamAccountName = $user


    $title = 'Get Password@USMC.gov' 
    $msg = 'Enter Password For New Privileged Account:' 
    $InputUser = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title) 
    $password=$InputUser.trim() 


    #This next line can be changed to JARHD/AdminUsers,
    $ou = "OU=Provision,OU=Users,OU=JARHD,OU=Agencies,DC=USMC,DC=net" 
    $FromRegularAccount = Get-ADUser -Identity ($XSamAccountName) -Properties DisplayName,USMCOfficeID, PersonGuid, ExtensionAttribute8, extensionattribute9, givenname, sn, streetaddress, city, postalcode, st, telephoneNumber, company, department, Office, Title, USMCAgencyAbbreviation
    
    
    
    $OldFirstname = $($FromRegularAccount.givenname)
    $OldFirstname = "IO." + $OldFirstname
    $OldLastname = $($FromRegularAccount.sn)
    $username = $OldFirstname + "."+ $Oldlastname
    

    #This next part gets the DisplayName from the Regular account and puts "IO."  in front of the firstname.  
    #This next part prepends "IO." to the firstname in the DisplayName...From the Regular Account
    #Good pattern is like this: Jones, Joseph - JARHD-RECON, Kansas City, MO
    #...This will not work if the Regular Account DisplayName is not in this format WITH THREE COMMAS !!!.  
   
    #This next part takes the $OldDisplayName, pulls it apart and puts IO in it and puts it back together
    
    #Need somr kind of a test right here
    #If good Pattern (with three commas like this: Jones, Joseph - JARHD-RECON, Kansas City, MO
    #Then do this  
    $OLdDisplayName = $($FromRegularAccount.DisplayName)
    $aa = $OLdDisplayName.Split(",")[0]
    $aa = $aa + ","
    $bb = $OLdDisplayName.Split(",")[1]
    $bb = "IO." + $bb + ","
    $bb = $bb -Replace "IO. ", " IO."   #This line takes the space out
    $cc = $OLdDisplayName.Split(",")[2]
    $cc =  (Get-Culture).TextInfo.ToTitleCase($cc).ToLower() 
    $cc =  (Get-Culture).TextInfo.ToTitleCase($cc)
    $cc = $cc.Trimend()
    $cc = $cc -replace "Sw$" , "sw".toupper()
    $cc = $cc + ","
    $dd = $OLdDisplayName.Split(",")[3] 
    $OLdDisplayName = $aa + $bb + $cc + $dd
   
    #Else
    #Do This
    #If the above DisplayName does not work, use this.  This puts it together 
    #These next three lines work if you need it, just take the comment # out.... of the next three lines
    #If ($($FromRegularAccount.ExtensionAttribute8) -eq "Contractor"){$OldDisplayName = $($FromRegularAccount.sn) + ", " + "IO." + $($FromRegularAccount.givenname) + " (CTR)" + " - " + $($FromRegularAccount.USMCAgencyAbbreviation) + ", " + $($FromRegularAccount.City) + ", " + $($FromRegularAccount.st)}
    #Else
    #    {$OldDisplayName = $($FromRegularAccount.sn) + ", " + "IO." + $($FromRegularAccount.givenname) + " - " + $($FromRegularAccount.USMCAgencyAbbreviation) + ", " + $($FromRegularAccount.City) + ", " + $($FromRegularAccount.st)} 




	#Check to see if the user already exists in AD
	if (Get-ADUser -F {SamAccountName -eq $Username})
	{
		 #If user does exist, give a warning
		 Write-Warning "A user account with username $Username already exist in Active Directory."
	}
	else
	{
		#User does not exist then proceed to create the new user account
		
        #Account will be created in the OU hard coded in this scripy on line 17
		New-ADUser `
            -SamAccountName $Username `
            -UserPrincipalName "$Username@USMC.net" `
            -Name "$OldFirstname.$OldLastname" `
            -GivenName $OldFirstname `
            -Surname $OldLastname `
            -Enabled $True `
            -DisplayName $OLdDisplayName `
            -Path $OU `
            -City $($FromRegularAccount.City) `
            -Company $($FromRegularAccount.company)  `
            -State $($FromRegularAccount.st) `
            -StreetAddress $($FromRegularAccount.streetaddress) `
            -OfficePhone $($FromRegularAccount.telephonenumber)  `
            -Description $($FromRegularAccount.Description) `
            -Department $($FromRegularAccount.department) `
            -Office $($FromRegularAccount.office) `
            -postalcode $($FromRegularAccount.postalcode) `
            -AccountPassword (convertto-securestring $Password -AsPlainText -Force) -ChangePasswordAtLogon $True
            
                     
             set-aduser -identity $username -smartcardlogonrequired $false
             Set-ADUser -identity $username -AccountNotDelegated $true
            
           
            Set-ADUser -Identity $username -Replace @{"ExtensionAttribute3"="RECON"}
            Set-ADUser -Identity $username -Replace @{"extensionAttribute9"="JARHD-RECON"}
            Set-ADUser -Identity $username -Replace @{"USMCAgencyAbbreviation"="JARHD-RECON"}
            Set-ADUser -Identity $username -Replace @{"c"="US"}
            Set-ADUser -Identity $username -Replace @{"co"="United States"}
            Set-ADUser -Identity $username -Replace @{"countryCode"="840"} 
            Set-ADUser -Identity $username -Replace @{"USMCOfficeID" = $($FromRegularAccount.USMCOfficeID)}
            Set-ADUser -Identity $username -Replace @{"EmployeeNumber" = $($FromRegularAccount.PersonGuid)}
            Set-ADUser -Identity $username -Replace @{"ExtensionAttribute8" = $($FromRegularAccount.ExtensionAttribute8)}
            Set-ADUser -Identity $username -Replace @{"Title" = $($FromRegularAccount.Title)}

That’s a lot of code to digg through. And it sounds like you’re asking for an enhancement or a review of your script and not for help with a particular piece of code you wrote. You didn’t even ask a question. :smirk:

IMHO you’re trying to approach this task at the wrong point. Following word for word the requirements you described you could use in a simple case a regular expression to test for the goodness of the display name like this:

'Jones, Joseph - JARHD-RECON, Kansas City, MO' -match '.+,.+,.+,.+'

This check would return a $true.

BUT … on the other hand that wouldn’t be a quality indicator at all since you do not check the individual parts for plausibility. With the same pattern you’d get the same result for the following check:

'Nonsense, comb1n3d with, even m0re non5ense, %&$()/=' -match '.+,.+,.+,.+'

I think it would be easier, or even more effective actually, to check the individual components in the first place and simply combine them later on.

And BTW: There are better ways to join some strings together like the -join operator. Here’s an example:

'LastName','FirstName','Agency','City','State' -join ', '

Or … if you don’t want to have a comma between ALL parts you could use the -f format operator like this:

'{0}, {1} - {2}, {3}, {4}' -f 'LastName', 'FirstName', 'Agency', 'City', 'State'

Regardless of that there are a lot of bad habits and bad styles in your code. You may consider to change it to make your code more robust, easier to read and to understand and way easier to maintain.

You should urgently consider avoiding to use backticks as there are error prone and usually unnecessary. A backtick is not a line continuation character - it is an escape character. And if the character you escape is a linebreak it works as expected. But if you accidentially add a space before the linebreak it breaks your code and it is hard to debug. Instead you should use splatting. Here you can read more about:

To create a new AD user based on another already existing AD user - maybe a prepared template user - you can use the so called instance method of the cmdlet New-ADUser.

https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd378959(v=ws.10)?redirectedfrom=MSDN

Instead of calling a single cmdlet 10 times you should think about using a loop or even more professional use the proper way PowerShell offers … like this:

$HashTable = @{
    "ExtensionAttribute3"    = "RECON"
    "extensionAttribute9"    = "JARHD-RECON"
    "USMCAgencyAbbreviation" = "JARHD-RECON"
    "c"                      = "US"
    <# and so on and on ... I think you get the idea ;-)  #>
}
Set-ADUser -Identity $username -Replace $HashTable

And last but not least you may read about some general best practices and styles recommended to improve your code:

1 Like

Olaf, Thanks very much. You gave me what I needed when you said:
…test for the goodness of the display name like this:

'Jones, Joseph - JARHD-RECON, Kansas City, MO' -match '.+,.+,.+,.+'

This check would return a $true .

So I extrapolated and wrote:

$GoodPattern = (', Joseph - JARHD-RECON, Kansas City, MO' -match '.+,.+,.+,.+')

Then tested with this:

if ( $GoodPattern )
{
    Write-Output "The condition was true"
}
else
{
    Write-Output "The condition was false"
}

And you are right, there is no quality, no plausibility check here, that would take a human eye.
And thank you for your other pointers. I know my style reeks of inexperience. I will eagerly study all your pointers, especially splatting.

Finally, the professors of English in college emphasize one truth: If you want to learn how to write well, you must first read good books. Classes in grammar are not enough.

I believe it is the same for PowerShell. I learn much more quickly when I see an example. Then I start to learn what the HELP and other syntax explanations really mean.

For example, I previously read the HELP on - instance method of the cmdlet New-ADUser But I gave up because I did not understand it - and I could not find an example.

Any good example of syntax should be very elementary with no advanced syntax of anything, whether related to the immediate subject or not. But that style of explaining requires great patience and more lengthy exposition.

It’s a kind of funny and weird at the same time that the only thing you took from all the tipps I gave is the bad coding example. :thinking: :wink:

Some topics just have a certain level of complexity. You can’t quiet explain an internal combustion engine if you can’t expect the other person to know what a piston is, what a cylinder is, and what a crankshaft is and so on.

And sometimes it’s best to figure one thing out for yourself. :wink: … it’s really not that hard. :point_up_2:t4:

First you specify the server, the template user and the attributes you want to use as a blueprint for your new user:

$Server = 'DC_01'
$sAMAccountName = 'JonDoe'

$PropertyList = @(
    'Department'
    'Manager'
    'Description'
    'Company'
    'City'
    'co'
    'Office'
    'StreetAddress'
    'PostalCode'
    'POBox'
    'State'
    'HomePage'
)

Now you can query the AD for the template user:

$BluePrint = 
    Get-ADUser -Identity $sAMAccountName -Properties $PropertyList -Server $Server

Then - if you want to create the new user in the same OU - you have to remove the CN from the DistinguishedName to determine the OU of the template user. Therefor we need a little bit string treatment unfortunately.

$OU = 'OU=' + ($BluePrint.DistinguishedName -split ",OU=",2)[1]

To avoid such string acrobatics you could use the PWSH module from Bill Steward PowerShell-ADName.

Now that you have everything you need from the template user you specify the new properties you want to use for the new user:

$NewADUserParams = @{
    Instance          = $BluePrint
    SamAccountName    = 'sAMAccountName'
    UserPrincipalName = 'UserPrincipalName@contoso.com'
    Name              = 'Common Name'
    AccountPassword   = (ConvertTo-SecureString -AsPlainText 'p@ssw0rd' -Force)
    GivenName         = 'GiveName'
    Surname           = 'SurName'
    Path              = $OU
    Server            = $Server
}

The last step is to create the new user with the New-ADUser cmdlet like this:

New-ADUser @NewADUserParams

Test it! Play around with it! Change it to your needs! It’d make your life a little easier. :wink:

Olaf, Good Sunday morning from here near Kansas City.
Thank you for your great efforts in teaching me. I take your words to heart and I do try to use the help.
You say I took the bad code?
It seems great to me because it works. And I mean to look for the Help on this kind of thing so I can write other kinds of pattern tests too.

And I am certainly in favor of learning and writing code so it will make my life easier, as you say.
And I am certainly in favor of code that is professional in appearance and easy to read and maintain. Best Practices and effecient, fast code seems like worthy goals too.

And I will study the code you explained.

1 Like