3

We have a few imports via PowerShell in to Active Directory that have a couple fields that come across as an empty string from the datasource, but need to be set as $null within Active Directory.

Since there are quite a few of these fields, I attempted to create a function that will convert an empty string to $null.

The trouble is that if I set the variable back to itself, it remains an empty string. If I set it as a new variable, it works fine.

function Get-ValueOrNull
{
    param(
        [Parameter(Mandatory=$true)]
        [AllowEmptyString()]
        [string]$Value
    )

    if ([string]::IsNullOrEmpty($Value))
    {
        return $null
    }

    return [string]$Value
}

function Test-Function
{
    param(
        [Parameter(Mandatory=$true)]
        [AllowEmptyString()]
        [string]$TestValue
    )
    $TestValue = Get-ValueOrNull -Value $TestValue
    $TestValue2 = Get-ValueOrNull -Value $TestValue

    Write-Host "TestValue: $($TestValue -eq $null)"
    Write-Host "TestValue2: $($TestValue2 -eq $null)"
}

Test-Function -TestValue ""

Here the output is

PS C:\> .\Test-Function.ps1
TestValue: False
TestValue2: True

This is clearly something I'm not understanding about Types in PowerShell function parameters. I can change the [string]$TestValue to $TestValue, and it will work.

function Test-Function
{
    param(
        [Parameter(Mandatory=$true)]
        [AllowEmptyString()]
        $TestValue
    )
    ...
}
...

Output:

PS C:\> .\Test-Function.ps1
TestValue: True
TestValue2: True

The reason I'd like to preserve the [string] parameter type is to enforce that it should be a string or an empty string. Can someone explain what is going on here?

1 Answer 1

5

Once you've casted the variable as opposed to the value being assigned you are strictly typing that variable.

This is easier to see with an [int] because basically anything can be casted to a [string] successfully:

$v = [int]'5'
$v.GetType()  # int

$v = 'hello'
$v.GetType()  # string

[int]$v = '5'
$v.GetType()  # int

$v = 'hello'
# Exception:
# Cannot convert value "hello" to type "System.Int32". Error: "Input string was not in a correct format."

When you type a parameter, the variable that contains the parameter is the same way; you can reassign it, but the right side must be assignable / castabale / convertible to the left side's type.

A $null cast as [string] is an empty string:

([string]$null) -eq ([string]::Empty)  # True

You can still strongly type your parameter, if you use a different intermediate variable in the function that isn't, as you demonstrated with $TestValue2.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.