How do you get powershell to set a default value without using IF statements?

I have a bunch of parameters in my actual function. Then I use New-ADUser to create an account - the problem is the parameters aren’t mandatory - if I don’t include an argument for each I get errors that say - “Can’t pass in a $null value” - how do I get it so that each value gets a default value and no null if I don’t include the parameter when running it?

$Attributes = @{
Name = $DisplayName
Enabled = $True
SamAccountName = $SamAccountName
UserPrincipalName = “$SamAccountName@$PrimaryDomain”
DisplayName = $DisplayName
GivenName = $FirstName
EmailAddress = “$SamAccountName@$PrimaryDomain”
Surname = $LastName
AccountPassword = $Credential
OfficePhone = $OfficePhone
Manager = $Manager
CannotChangePassword = $CannotChangePassword
ChangePasswordAtLogon = $ChangePasswordAtLogon
PasswordNeverExpires = $PasswordNeverExpires
Description = $Description
Path = $Path
}
New-ADUser @Attributes # Create a new user

Short of something like this I have no idea how to do this

if ($ProxyDomain -eq $null) { $ProxyDomain = "DefaultProxyDomain" }
if ($Path -eq $null) { $Path = "DefaultPath" }
if ($OfficePhone -eq $null) { $OfficePhone = "DefaultOfficePhone" }
if ($Manager -eq $null) { $Manager = "DefaultManager" }
if ($Description -eq $null) { $Description = "DefaultDescription" }
if ($CannotChangePassword -eq $null) { $CannotChangePassword = $true }
if ($ChangePasswordAtLogon -eq $null) { $ChangePasswordAtLogon = $false }
if ($PasswordNeverExpires -eq $null) { $PasswordNeverExpires = $false }

Here is the full code if it helps:

function New-UserHire {

# In-progress


<#
.SYNOPSIS
Fully creates a new user account

.DESCRIPTION
Creates a new user account, sets a secure password for the account, adds proxy addresses to on-premise account,
add user to relevant groups, runs a delta sync, licenses out office 365 mailbox, 
sends an encrypted email with all relevant information to a defined email

.PARAMETER Credential
Credential for new user. Set a password as a secure string. You can either set a password automatically without running the function with -Credential - it will automatically prompt you, or you can create a secure string object first and pass it in

.PARAMETER FirstNameDotLastNameConvention
Pass in either $true or $false if the username is first.last - Example: Bob Builder -> bob.builder

.PARAMETER FirstInitialLastNameConvention
Pass in either $true or $false if the username is flast - Example: Bob Builder -> bbuilder

.PARAMETER Email
Email address of the employee - if you don't include an email - the email will default to the on-premise UPN of the new user

.PARAMETER ProxyDomain
Proxy address of the employee - if you don't include a domain, no proxy address will be included and email will match on-premise UPN.
Example bobsbuilders.com is the proxy domain - the email would end up being bob.builder@bobsbuilders.com 

.PARAMETER FirstName
First name of the new user

.PARAMETER LastName
Last name of the new user 

.PARAMETER Path 
Distinguished name attribute of the OU where you want the user account to be created in. 

.PARAMETER OfficePhone
Office phone number for the new user

.PARAMETER Manager 
Username of the manager of the new user

.PARAMETER Description
Description for the new user object

.PARAMETER CannotChangePassword 
Set to either $true or $false - Used by New-ADUser to determine if the user is allowed to change their own account password

.PARAMETER ChangePasswordAtLogon 
Set to either $true or $false - Used by New-ADUser to determine if the user is prompted to change their password upon first logon

.PARAMETER PasswordNeverExpires
Set to either $true or $false - Used by New-ADUser to determine if the users password should never expire

.EXAMPLE
Manually pass in a secure string (FirstNameDotLastName User)

$SecureString = ConvertTo-SecureString "MySecurePassword1$" -AsPlainText -Force
New-UserHire -FirstNameDotLastNameConvention $true -FirstInitialLastNameConvention $false -FirstName "Bob" -LastName "Builder" -Path "OU=Shane Users,DC=ad,DC=smhcomputers,DC=com" -OfficePhone "561-319-5196" -Manager "shane" -Description "This is a user" -CannotChangePassword $true -ChangePasswordAtLogon $true -Credential $SecureString

.EXAMPLE
Run without passing in a value for credential - you will be prompted for a credential for the new user (FirstNameDotLastName User)
New-UserHire -FirstNameDotLastNameConvention $true -FirstInitialLastNameConvention $false -FirstName "Bob" -LastName "Builder" -Path "OU=Shane Users,DC=ad,DC=smhcomputers,DC=com" -OfficePhone "561-319-5196" -Manager "shane" -Description "This is a user" -CannotChangePassword $true -ChangePasswordAtLogon $true

.EXAMPLE
Create a user with a proxy address as their primary email (FirstNameDotLastName User)
New-UserHire -FirstNameDotLastNameConvention $true -FirstInitialLastNameConvention $false -FirstName "Bob" -LastName "Builder" -ProxyDomain "smhcomputers.com"

.NOTES
Must be ran from a Domain Controller as either a user with domain administrator, local administrator, or server operator role


#>


[CmdletBinding()]
Param (   
    [Parameter(ValueFromPipeline = $True, Mandatory = $True)]
    [ValidateNotNull()]
    [SecureString]$Credential,

    [Parameter(Mandatory = $True)] # Boolean - takes $true or $false
    [boolean]$FirstNameDotLastNameConvention,
    
    [Parameter(Mandatory = $True)] # Boolean - takes $true or $false
    [boolean]$FirstInitialLastNameConvention,

    [Parameter(Mandatory = $False)]
    [String]$EmailAddress,

    [Parameter(Mandatory = $False)]
    [String]$ProxyDomain,

    [Parameter(Mandatory = $True)]
    [String]$FirstName,

    [Parameter(Mandatory = $True)]
    [String]$LastName,

    [Parameter(Mandatory = $False)]
    [String]$Path,

    [Parameter(Mandatory = $False)]
    [String]$OfficePhone,

    [Parameter(Mandatory = $False)]
    [String]$Manager,

    [Parameter(Mandatory = $False)]
    [String]$Description,

    [Parameter(Mandatory = $False)] # Boolean - takes $true or $false
    [boolean]$CannotChangePassword,

    [Parameter(Mandatory = $False)] # Boolean - takes $true or $false
    [boolean]$ChangePasswordAtLogon,

    [Parameter(Mandatory = $False)] # Boolean - takes $true or $false
    [boolean]$PasswordNeverExpires 
)

$PrimaryDomain = Get-ADDomain | Select-Object -ExpandProperty DNSRoot
$DisplayName = $FirstName + " " + $LastName

if ($FirstNameDotLastNameConvention -eq $True) {
    $SamAccountName = $FirstName + "." + $LastName
}
elseif ($FirstInitialLastNameConvention -eq $True) {
    $SamAccountName = $FirstName[0] + $LastName
}

if ($EmailAddress -eq $null) {
    $EmailAddress = "$SamAccountName@$PrimaryDomain"
}

try {

    $Attributes = @{
        Name                  = $DisplayName
        Enabled               = $True
        SamAccountName        = $SamAccountName
        UserPrincipalName     = "$SamAccountName@$PrimaryDomain"
        DisplayName           = $DisplayName
        GivenName             = $FirstName
        EmailAddress          = "$SamAccountName@$PrimaryDomain"
        Surname               = $LastName
        AccountPassword       = $Credential
        OfficePhone           = $OfficePhone
        Manager               = $Manager
        CannotChangePassword  = $CannotChangePassword
        ChangePasswordAtLogon = $ChangePasswordAtLogon
        PasswordNeverExpires  = $PasswordNeverExpires 
        Description           = $Description
        Path                  = $Path
    }
    New-ADUser @Attributes # Create a new user object and pass in values stored in parameters

}

catch {

    Write-Warning "Error: Check parameters provided"

}

if (-not $ProxyDomain -eq $null ) { # If $Proxy Domain variable is passed in set a proxy address
Set-ADUser $SamAccountName -Add @{ProxyAddresses = "SMTP:" + "$SamAccountName@$ProxyDomain" }

}

Steps

Check if the user account already exists in AD - Done - New-ADUser does this

Create a user account - Done

set a secure password - Done

add proxy addresses to on-premise account

add user to relevant groups

runs a delta sync

licenses out office 365 mailbox

sends an encrypted email with all relevant information to a defined email

Creates a log file with relevant information regarding new hire

} # End function

You could just give your parameters default values:

function Test-Function {
    [CmdletBinding()]
    Param (   
    [Parameter(Mandatory = $True)]
    [String]$FirstName,

    [Parameter(Mandatory = $True)]
    [String]$LastName,

    [Parameter(Mandatory = $False)]
    [String]$Description = 'Account Description',

    [Parameter(Mandatory = $False)]
    [String]$OfficePhone = '01234 567 890'
    )

    [PSCustomObject] @{
        FirstName    = $FirstName
        Surname      = $LastName
        Description  = $Description
        OfficePhone  = $OfficePhone
    }
}

$params = @{
    FirstName   = 'Buffy'
    LastName    = 'Summers'
    OfficePhone =  '(805) 555-8966'
}

Test-Function @params

Alternatively, if you’re happy with empty rather than default values, you could make sure that your function’s parameters match the parameters expected by New-ADUser and build your $Attributes hashtable from the parameters that were passed to the function:

function Test-Function {
    [CmdletBinding()]
    Param (   
    [Parameter(Mandatory = $True)]
    [String]$FirstName,

    [Parameter(Mandatory = $True)]
    [String]$Surname,

    [Parameter(Mandatory = $False)]
    [String]$Description = 'Account Description',

    [Parameter(Mandatory = $False)]
    [String]$OfficePhone = '01234 567 890'
    )

    $Attributes = @{}

    foreach ($boundParam in $PSBoundParameters.GetEnumerator()) {
        $Attributes.Add($boundParam.Key,$boundParam.Value)
    }

    $Attributes
}

$params = @{
    FirstName   = 'Buffy'
    Surname     = 'Summers'
    OfficePhone =  '(805) 555-8966'
}

Test-Function @params
1 Like

Wouldn’t it be even possible to add the optional parameters even only optional to the hashtable by using an if statement inside $Attributes foreach loop? :thinking:

Sorry, @Olaf, I’m not sure what you’re asking.

Let’s say you don’t know the office phone number for new employee yet. So you omit this parameter and therefor do not add it to the hashtable.

function Test-Function {
    [CmdletBinding()]
    Param (   
        [Parameter(Mandatory = $True)]
        [String]$FirstName,

        [Parameter(Mandatory = $True)]
        [String]$Surname,

        [Parameter(Mandatory = $False)]
        [String]$Description = 'Account Description',

        [Parameter(Mandatory = $False)]
        [String]$OfficePhone
    )

    $Attributes = @{}

    foreach ($boundParam in $PSBoundParameters.GetEnumerator()) {
        if ($boundParam.Value) {
            $Attributes.Add($boundParam.Key, $boundParam.Value)
        }        
    }
    $Attributes
}