PowerShell: $null and parameter type

One of those things that can take you ages to find out: I create a function where a parameters that can either have a string value or can be $null:

function doit
{
  param
  (
    [string]$a = $( throw "Missing: parameter a"),
    $b = $( throw "Missing: parameter b")
  )

  if ($a -eq $null) { Write-Host "a is null" } else { write-Host "a is not null" }
  if ($b -eq $null) { Write-Host "b is null" } else { Write-Host "b is not null" }
}

If I call this function with: doit $null $null

I get the following result:

a is not null
b is null

What happened: because I specified a type [string] for parameter a, the $null value gets casted to a string with value "". 

Published Sunday, December 10, 2006 1:05 PM by svdoever
Filed under: ,

Comments

Tuesday, July 24, 2007 10:56 AM by Nick

# re: PowerShell: $null and parameter type

Any idea on how to stop it from doing that?

It appears that Powershell does this cast even when calling into an assembly (such as the SharePoint API), and null != String.Empty.

Monday, February 11, 2008 10:16 AM by Mel Collins

# re: PowerShell: $null and parameter type

I have the same problem calling tfs method QueryLabels.

This code in Powershell

$labels =  $vcs.QueryLabels("REL_1_*","$/ProjectX",$null,$false)

is not hte same as this in C#

VersionControlLabel[] labels = vcs.QueryLabels("REL_1_*", "$/ProjectX", null, false);

Tuesday, February 12, 2008 6:47 AM by Mel Collins

# re: PowerShell: $null and parameter type

The only workaround I have been able to find for calling .Net assemblies is to write a cmdlet to wrap your call to .net assembly.  This works fine.

WriteObject(Vcs.QueryLabels(label, Scope, User, IncludeItems));

Full Code below:

using System;

using System.Collections.Generic;

using System.Text;

using System.Management.Automation;

using System.Collections;

using Microsoft.TeamFoundation.VersionControl.Client;

namespace WindowsPowerShell1

{

   [Cmdlet(VerbsCommon.Get, "Label", SupportsShouldProcess = true)]

   public class GetLabel : Cmdlet

   {

       private string label;

       private string scope;

       private VersionControlServer vcs;

       private string user;

       private bool includeItems;

       #region Parameters

       [Parameter(Position = 0,

           Mandatory = true,

           ValueFromPipelineByPropertyName = true,

           HelpMessage="The label name - * is wildcard")]

       [ValidateNotNullOrEmpty]

       public string Label

       {

           get { return label; }

           set { label = value; }

       }

       [Parameter(Position = 1,

          Mandatory = true,

          ValueFromPipelineByPropertyName = true,

          HelpMessage = "Scope")]

       [ValidateNotNullOrEmpty]

       public string Scope

       {

           get { return scope; }

           set { scope = value; }

       }

       [Parameter(Position = 2,

          Mandatory = true,

          ValueFromPipelineByPropertyName = true,

          HelpMessage = "VersionControlServer")]

       [ValidateNotNull]

       public VersionControlServer Vcs

       {

           get { return vcs; }

           set { vcs = value; }

       }

       [Parameter(Position = 3,

            Mandatory = false,

            ValueFromPipelineByPropertyName = true,

            HelpMessage = "VersionControlServer")]

       public string User

       {

           get { return user; }

           set { user = value; }

       }

       [Parameter(Position = 4,

            Mandatory = true,

            ValueFromPipelineByPropertyName = true,

            HelpMessage = "IncludeItems")]

       public bool IncludeItems

       {

           get { return includeItems; }

           set { includeItems = value; }

       }

       #endregion

       protected override void ProcessRecord()

       {

           try

           {

               WriteObject(Vcs.QueryLabels(label, Scope, User, IncludeItems));

           }

           catch (Exception)

           {

           }

       }

   }

}

Friday, May 02, 2008 4:02 PM by R. Praetorius

# re: PowerShell: $null and parameter type

Thanks much to Mr. Collins for his workaround

weblogs.asp.net/.../powershell-null-and-argument-types.aspx

Just what the Dr. ordered!

Tuesday, June 17, 2008 9:44 PM by R. Praetorius

# re: PowerShell: $null and parameter type

another workaround, shorter but probably slightly less efficient (although the overhead of a wildcarded QueryLabels invocation may swamp the difference):

[assuming the presence of James Manning's get-tfs.ps1 ( blogs.msdn.com/.../776141.aspx ) in your path]

$tfs = get-tfs $tfsServerName

$labels = $tfs.vcs.GetType().InvokeMember('QueryLabels', 'InvokeMethod', $null, $tfs.vcs, @($labelName, $scope, $null, $includeItems))

should get you QueryLabels results with a wildcarded owner.  At least it does for me.

Wednesday, March 28, 2012 8:47 AM by Amanda

# re: PowerShell: $null and parameter type

Wow! I could not even guess about it)) Not bad.

Leave a Comment

(required) 
(required) 
(optional)
(required)