Get username from full name - PowerShell function I would like your opinion of my PowerShell function. Does it follow conventions, and what could can I do to improve it. It is made to create LDAP friendly username from a full name in Serbian language.
function Get-UsernameFromFullName
{
    [CmdletBinding()]
    param
    (
        [Parameter(Position = 0, Mandatory = $true, ValueFromPipelineByPropertyName = $true)]
        [string]
        $FullName,

        [Parameter(Position = 1, Mandatory = $false, ValueFromPipelineByPropertyName = $true)]
        [ValidateSet('First', 'Last')]
        [string]
        $LastNamePosition = 'First'
    )
    
    $usernameComponents = $FullName.ToLower().Split(&quot; &quot;)

    switch ($LastNamePosition)
    {
        'First' { $firstName = $usernameComponents.Length -1; $lastName = 0 }
        'Last'  { $firstName = 0; $lastName = $usernameComponents.Length -1 }
        Default { $firstName = $usernameComponents.Length -1; $lastName = 0 }
    }

    $chars = ($usernameComponents.Get($firstName) + &quot;.&quot; + $usernameComponents.Get($lastName)).ToCharArray()

    foreach($char in $chars)
    {
        switch($char)
        {
            'ć' { $segment = &quot;c&quot; }
            'č' { $segment = &quot;c&quot; }
            'đ' { $segment = &quot;dj&quot; }
            'š' { $segment = &quot;s&quot; }
            'ž' { $segment = &quot;z&quot; }
            default { $segment = $char }
        }
        $Username += $segment
    }
    return $Username
}

Here is a link to GitHub page of the actual .psm1 file.
This is an example of the function usage:
Get-UsernameFromFullName -FullName &quot;Čedomir Đorđević&quot;

cedomir.djordjevic
Get-UsernameFromFullName -FullName &quot;JANKOV ZORAN&quot; 

zoran.jankov
Get-UsernameFromFullName -FullName &quot;Stojić Gradimir&quot;

gradimir.stojic
Get-UsernameFromFullName -FullName &quot;Vučićević R Željko&quot;

zeljko.vucicevic
Get-UsernameFromFullName -FullName &quot;Magda Boškić&quot; -LastNamePosition Last

magda.boskic
i think the comments cover the why of things, but please feel free to ask if you have any questions. [grin]
#region &gt;&gt;&gt; fake reading in a list of names
#    in real life, use Get-Content
$InStuff = @'
Čedomir Đorđević
JANKOV ZORAN 
Stojić Gradimir
Vučićević R Željko
Magda Boškić
'@ -split [System.Environment]::NewLine

&lt;# intended output
cedomir.djordjevic
zoran.jankov
gradimir.stojic
zeljko.vucicevic 
magda.boskic [lastname @ end]
#&gt;
#endregion &gt;&gt;&gt; fake reading in a list of names



function Get-UserNameFromFullName
    # your &quot;Get-UsernameFromFullName&quot; name leaves the &quot;N&quot; in &quot;Username&quot; in lowercase
    #    that is not consistent with your use of that in other names of items
    {

    &lt;#
    where is the Comment Based Help?
    #&gt;

    [CmdletBinding ()]
    Param
        (
        [Parameter (
            Position = 0,
            # the following are switches that default to &quot;$False&quot;
            #    that means there is no need to add &quot;= $True&quot;
            #    the simple presense of the attribute flips it to &quot;$True&quot;
            Mandatory,
            ValueFromPipeline,
            # the following requres the pipeline object contain a property named &quot;.FullName&quot;
            #    is that always going to be the case?
            #    if not, then the &quot;ValueFromPipeline&quot; above will handle bare values
            ValueFromPipelineByPropertyName
            )]
            [string]
            $FullName,

        [Parameter (
            Position = 1,
            # making this mandatory makes little sense when a default is supplied
            #Mandatory,
            # does it make any sense to use the following attribute?
            ValueFromPipelineByPropertyName
            )]
            # don't use &quot;First&quot; and &quot;Last&quot; for _position_ info when the same words are used for the name parts
            #    it's needlessly confusing
            #[ValidateSet ('First', 'Last')]
            [ValidateSet ('Start', 'End')]
            [string]
            $LastNamePosition = 'Start'
        )

    begin {}

    process
        {
        # properly supporting the pipeline requires one to have a &quot;process&quot; block.
        #    otherwise all code is run in a virtual &quot;end&quot; block ... and that does not correctly support pipeline input

        # mixing camelCase and PascalCase for variable names is confusing [*grin*] 
        #    the recommended style for PoSh is PascalCase
        #$usernameComponents = $FullName.ToLower().Split(&quot; &quot;)
        # the 2nd sample name has a trailing space
        #    the &quot;.Trim()&quot; removes that
        # good practice in PoSh is to avoid using double quotes since that can trigger unwanted expansion of $Vars
        $UserNameComponents = $FullName.Trim().ToLower().Split(' ')

        switch ($LastNamePosition)
            {
            'Start' {
                # &quot;index -1, index 0&quot; for the $UserNameComponents skips any middle name or initial
                $UserName = '{0}.{1}' -f $UserNameComponents[-1], $UserNameComponents[0]
                }
            'End' {
                $UserName = '{0}.{1}' -f $UserNameComponents[0], $UserNameComponents[-1]
                }
            # this is a binary choice, so the &quot;default&quot; is not needed
            #Default { $firstName = $UserNameComponents.Length -1; $lastName = 0 }
            }

        # there is no need to assign the output to anything
        #    whatever is left unassigned will be sent out
        # there is also no need for &quot;return&quot;
        #    that is disrecommeded since it gives the false impression that ONLY the item to its right will be returned
        # the &quot;-replace&quot; operator can be chained. so can the &quot;.Replace()&quot; method
        #    that allows us to skip breaking things into an array of chars
        $UserName -replace 
            'č', 'c' -replace
            'ć', 'c' -replace
            'đ', 'dj' -replace
            'š', 's' -replace
            'ž', 'z'

        } # end &gt;&gt;&gt; process

    end {}

    } # end &gt;&gt;&gt; function Get-UserNameFromFullName

run with all names, no parameters, and using the pipeline ...
$InStuff |
    Get-UserNameFromFullName

output ...
djordjevic.cedomir
zoran.jankov
gradimir.stojic
zeljko.vucicevic
boskic.magda

run with all parameters listed and only one input value ...
Get-UserNameFromFullName -FullName $InStuff[-1] -LastNamePosition End

output = magda.boskic