@@ -111,116 +111,173 @@ This function generates a unique UPN based on given name components and ensures
111111``` powershell
112112function Get-UniqueUPN
113113{
114- [CmdletBinding()]
115- param (
116- [Parameter(Mandatory = $true, ParameterSetName = "ADObject")]
117- [object]$ADObject,
114+ <#
115+ .SYNOPSIS
116+ Cmdlet will generate a forest wide unique UPN.
117+
118+ .DESCRIPTION
119+ Cmdlet will generate a forest wide unique UPN according to generation rules
120+ defined by the user.
118121
119- [Parameter(Mandatory = $true, ParameterSetName = "Strings")]
120- [string]$FirstName,
122+ Cmdlet accept different types of objects to generate the UPN to allow greater flexibility
121123
122- [Parameter(Mandatory = $true, ParameterSetName = "Strings")]
124+ ADObject - For example and object from Get-AdUser cmdlet
125+ Strings - Representing First Name, Last Name etc.
126+ DirectoryService Objects - For example when using native .Net methods to retrieve the identity
127+
128+ .PARAMETER ADObject
129+ An ADObject for example output of the Get-ADUser cmdlet
130+
131+ .PARAMETER FirstName
132+ A string representing the First Name of the user
133+
134+ .PARAMETER LastName
135+ A string representing the Last Name of the user
136+
137+ .PARAMETER MiddleName
138+ A string representing the Middle Name of the user, parameter is optional.
139+
140+ .PARAMETER UPNSuffix
141+ A string representing the UPN suffix to be used.
142+
143+ .PARAMETER FirstNameFormat
144+ A string representing the format to be for the First Name part of the UPN.
145+
146+ .PARAMETER LastNameFormat
147+ A string representing the format to be for the Last Name part of the UPN.
148+
149+ .PARAMETER IncludeMiddleName
150+ When paramenter is specified user Middle Name, if present, will be included in the UPN generation process.
151+
152+ .PARAMETER ADServer
153+ A string representing the name of the AD Domain Controller that will be used to query Active Directory.
154+
155+ If no server is specified the closest Global Catalog will be automatically selected.
156+
157+ .PARAMETER Separator
158+ A string representing the separator to be used between UPN parts, defaults to a '.'.
159+ #>
160+
161+ [CmdletBinding(DefaultParameterSetName = 'Strings')]
162+ param
163+ (
164+ [Parameter(ParameterSetName = 'ADObject',
165+ Mandatory = $true)]
166+ [object]$ADObject,
167+ [Parameter(ParameterSetName = 'Strings',
168+ Mandatory = $true)]
169+ [ValidateNotNullOrEmpty()]
170+ [string]$FirstName,
171+ [Parameter(ParameterSetName = 'Strings',
172+ Mandatory = $true)]
173+ [ValidateNotNullOrEmpty()]
123174 [string]$LastName,
124-
125- [Parameter(ParameterSetName = "Strings" )]
175+ [Parameter(ParameterSetName = 'Strings')]
176+ [ValidateNotNullOrEmpty( )]
126177 [string]$MiddleName,
127-
128178 [Parameter(Mandatory = $true)]
179+ [ValidateNotNullOrEmpty()]
129180 [string]$UPNSuffix,
130-
131- [string]$FirstNameFormat = "Full",
181+ [ValidateSet('FullName', 'FirstLetter', IgnoreCase = $true)]
182+ [ValidateNotNullOrEmpty()]
183+ [string]$FirstNameFormat = 'Full',
184+ [ValidateSet('FullName', 'FirstLetter', IgnoreCase = $true)]
185+ [ValidateNotNullOrEmpty()]
186+ [string]$LastNameFormat = 'FullName',
132187 [switch]$IncludeMiddleName,
133- [string]$DuplicateSuffix = "Numeric",
134- [string]$CustomDuplicateSuffix ,
135- [string]$Server,
136- [string]$Separator = "."
188+ [ValidateNotNullOrEmpty()]
189+ [string]$ADServer ,
190+ [ValidateNotNullOrEmpty()]
191+ [string]$Separator = '.'
137192 )
138-
139- try
193+
194+ if ($PSCmdlet.ParameterSetName -eq 'ADObject')
140195 {
141- if ($PSCmdlet.ParameterSetName -eq " ADObject" )
196+ switch ($ADObject.GetType().FullName )
142197 {
143- Write-Verbose "Processing AD Object"
144- switch ($ADObject.GetType().FullName)
198+ 'Microsoft.ActiveDirectory.Management.ADUser'
199+ {
200+ [string]$firstName = $ADObject.GivenName
201+ [string]$lastName = $ADObject.Surname
202+ [string]$middleName = $ADObject.MiddleName
203+
204+ break
205+ }
206+ 'System.DirectoryServices.DirectoryEntry'
207+ {
208+ [string]$firstName = $ADObject.Properties['givenName'][0]
209+ [string]$lastName = $ADObject.Properties['sn'][0]
210+ [string]$middleName = $ADObject.Properties['middleName'][0]
211+
212+ break
213+ }
214+ 'System.DirectoryServices.SearchResult'
145215 {
146- "Microsoft.ActiveDirectory.Management.ADUser"
147- {
148- $firstName = $ADObject.GivenName
149- $lastName = $ADObject.Surname
150- $middleName = $ADObject.MiddleName
151- break
152- }
153- "System.DirectoryServices.DirectoryEntry"
154- {
155- $firstName = $ADObject.Properties["givenName"][0]
156- $lastName = $ADObject.Properties["sn"][0]
157- $middleName = $ADObject.Properties["middleName"][0]
158- break
159- }
160- "System.DirectoryServices.SearchResult"
161- {
162- $firstName = $ADObject.Properties["givenName"][0]
163- $lastName = $ADObject.Properties["sn"][0]
164- $middleName = $ADObject.Properties["middleName"][0]
165- break
166- }
167- default
168- {
169- throw "Unsupported AD object type: $($ADObject.GetType().FullName)"
170- }
216+ [string]$firstName = $ADObject.Properties['givenName'][0]
217+ [string]$lastName = $ADObject.Properties['sn'][0]
218+ [string]$middleName = $ADObject.Properties['middleName'][0]
219+
220+ break
221+ }
222+ default
223+ {
224+ throw "Unsupported AD object type: $($ADObject.GetType().FullName)"
171225 }
172226 }
173- else
227+ }
228+ else
229+ {
230+ [string]$firstName = $FirstName
231+ [string]$lastName = $LastName
232+ [string]$middleName = $MiddleName
233+ }
234+
235+ # Format first name
236+ $firstName = switch ($FirstNameFormat)
237+ {
238+ 'FullName'
174239 {
175- Write-Verbose "Processing string inputs"
176- $firstName = $FirstName
177- $lastName = $LastName
178- $middleName = $MiddleName
240+ $firstName
179241 }
180-
181- Write-Verbose "First Name: $firstName, Last Name: $lastName, Middle Name: $middleName"
182-
183- $firstName = switch ($FirstNameFormat)
242+ 'FirstLetter'
184243 {
185- "Full" { $firstName }
186- "FirstLetter" { $firstName.Substring(0, 1) }
187- default { $firstName }
244+ $firstName.Substring(0, 1)
188245 }
189-
190- $middleNamePart = if ($IncludeMiddleName -and $middleName)
246+ }
247+
248+ # Format last name
249+ $LastName = switch ($FirstNameFormat)
250+ {
251+ 'FullName'
191252 {
192- "$Separator$middleName"
253+ $LastName
193254 }
194- else { "" }
195-
196- $baseUPN = "$firstName$middleNamePart$Separator$lastName@$UPNSuffix".ToLower()
197- Write-Verbose "Base UPN: $baseUPN"
198-
199- $uniqueUPN = $baseUPN
200- $counter = 1
201-
202- while (Test-UPNExist -UPN $uniqueUPN -Server $Server)
255+ 'FirstLetter'
203256 {
204- Write-Verbose "UPN $uniqueUPN already exists, generating alternative"
205- if ($DuplicateSuffix -eq "Numeric")
206- {
207- $uniqueUPN = "{0}{1}@{2}" -f ($baseUPN.Split('@')[0]), $counter, $UPNSuffix
208- }
209- else
210- {
211- $uniqueUPN = "{0}{1}@{2}" -f ($baseUPN.Split('@')[0]), $CustomDuplicateSuffix, $UPNSuffix
212- }
213- $counter++
257+ $LastName.Substring(0, 1)
214258 }
215-
216- Write-Verbose "Final Unique UPN: $uniqueUPN"
217- return $uniqueUPN
218259 }
219- catch
260+
261+ # Use middle name
262+ [string]$middleNamePart = if ($IncludeMiddleName -and $MiddleName)
263+ {
264+ '{0}{1}' -f $Separator, $MiddleName
265+ }
266+
267+ # Setup required attributes
268+ [string]$baseUPN = ('{0}{1}{2}{3}@{4}' -f $FirstName, $middleNamePart, $Separator, $LastName, $UPNSuffix).ToLower()
269+ [string]$uniqueUPN = $baseUPN
270+ [int]$counter = 1
271+
272+ while (Test-UPNExist -UPN $uniqueUPN -Server $ADServer)
220273 {
221- Write-Error "Error generating UPN: $_"
222- throw
274+
275+ $uniqueUPN = '{0}{1}@{2}' -f ($baseUPN.Split('@')[0]), $counter, $UPNSuffix
276+
277+ $counter++
223278 }
279+
280+ return $uniqueUPN
224281}
225282```
226283
0 commit comments