Accepting a pipeline value into a function

Can anyone advise on the following?  I am trying to pipe the property Name from Get-ADComputer to a custom made function...

        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [ValidateNotNull()]
        [ValidateNotNullOrEmpty()]
        [Alias('HostName','Server','IPAddress','CN','Name')]
        [string[]]$ComputerName

The error is a blank ComputerName parameter...

Cannot validate argument on parameter 'ComputerName'. The argument is null or empty. Provide anargument that is not null or empty, and then try the command again.

July 9th, 2015 11:14am

Since you have made the parameter mandatory, i believe there is no need to use either [ValidateNotNull()] or [ValidateNotNullOrEmpty()] attributes.

        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [Alias('HostName','Server','IPAddress','CN','Name')]
        [string[]]$ComputerName
Also, please make sure the property name from Get-ADComputer is nither Null or empty.
Free Windows Admin Tool Kit Click here and download it now
July 9th, 2015 11:47am

Since you have made the parameter mandatory, i believe there is no need to use either [ValidateNotNull()] or [ValidateNotNullOrEmpty()] attributes.

        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [Alias('HostName','Server','IPAddress','CN','Name')]
        [string[]]$ComputerName
Also, please make sure the property name from Get-ADComputer is nither Null or empty.
July 9th, 2015 11:48am

Correct however the error message is clearer when declaring validation.

Without...

Cannot bind argument to parameter 'ComputerName' because it is an empty array.

This isn't my issue anyway. I just want to know what I need to change in order for my function to allow me to use the Name from Get-ADComputer into my functions ComputerName property.

Free Windows Admin Tool Kit Click here and download it now
July 9th, 2015 11:57am

did you expanded the property ? 
Get-ADComputer -Filter * | Select-Object -ExpandProperty Name


July 9th, 2015 12:06pm

did you expanded the property ? 
Get-ADComputer -Filter * | Select-Object -ExpandProperty Name


Free Windows Admin Tool Kit Click here and download it now
July 9th, 2015 12:07pm

function Test-Call{
    Param(
        [Parameter(Mandatory=$true,
            ValueFromPipeline=$true,
            ValueFromPipelineByPropertyName=$true,
            Position=0
         )]
        [ValidateNotNullOrEmpty()]
	[Alias('ComputerName','IPAddress','CN')]
        [string[]]$Name
    )
    Process{
       $name
    }
}

get-adcomputer -Filter * | Test-Call

Like this:

July 9th, 2015 12:19pm

Indeed jrv that works but also means my property is now named Name rather than ComputerName.

I was under the impression that because I had alias of Name it would take this down the pipeline and apply it to ComputerName. Is this not correct?

Also "Select -ExpandProperty Name" works.
  • Edited by AJPalmer 14 hours 44 minutes ago
Free Windows Admin Tool Kit Click here and download it now
July 9th, 2015 12:25pm

Indeed jrv that works but also means my property is now named Name rather than ComputerName.

I was under the impression that because I had alias of Name it would take this down the pipeline and apply it to ComputerName. Is this not correct?

Also "Select -ExpandProperty Name" works.
  • Edited by AJPalmer 14 hours 36 minutes ago
July 9th, 2015 12:26pm

Expand property works because it fulfills the position=0 criteria.

Try this:
Get-Process |select -expand handles | Test-Call

To get multiple pipeline names you will need to sue parameter sets.

Free Windows Admin Tool Kit Click here and download it now
July 9th, 2015 12:36pm

Yes that works.

Is there nothing I can do to get it to accept the Name property as the ComputerName property in the function without having to do the select-object?

I understand that PowerShell will match the two properties if they share the same 'Name' but I would sooner keep my script to use the property ComputerName.

July 9th, 2015 12:53pm

Can you please pipe the Name property to Out-String before calling the function.

Something like this

  function test-call
	 {
	 	param(
					 [Parameter(Mandatory=$true,
				                   ValueFromPipeline=$true,
				                   ValueFromPipelineByPropertyName=$true,
				                   Position=0)]
				        [ValidateNotNull()]
				        [ValidateNotNullOrEmpty()]
				        [Alias('HostName','Server','IPAddress','CN','Name')]
				        [String[]]$ComputerName
	   )
	$ComputerName
	}
	
Get-Content "C:\servers.txt"| out-String |test-call 
 In my case C:\servers.txt has computers list. In your case it would be
Get-ADComputer -Filter * | Select -ExpandProperty Name | Out-String | Test-Call


Free Windows Admin Tool Kit Click here and download it now
July 9th, 2015 1:34pm

Can you please pipe the Name property to Out-String before calling the function.

Something like this

  function test-call
	 {
	 	param(
					 [Parameter(Mandatory=$true,
				                   ValueFromPipeline=$true,
				                   ValueFromPipelineByPropertyName=$true,
				                   Position=0)]
				        [ValidateNotNull()]
				        [ValidateNotNullOrEmpty()]
				        [Alias('HostName','Server','IPAddress','CN','Name')]
				        [String[]]$ComputerName
	   )
	$ComputerName
	}
	
Get-Content "C:\servers.txt"| out-String |test-call 
 In my case C:\servers.txt has computers list. In your case it would be
Get-ADComputer -Filter * | Select -ExpandProperty Name | Out-String | Test-Call


July 9th, 2015 1:36pm

Yes that works.

Is there nothing I can do to get it to accept the Name property as the ComputerName property in the function without having to do the select-object?

I understand that PowerShell will match the two properties if they share the same 'Name' but I would sooner keep my script to use the property ComputerName.


I repeat:

To get multiple pipeline names you will need to sue parameter sets.

Free Windows Admin Tool Kit Click here and download it now
July 9th, 2015 1:50pm

Since you have made the parameter mandatory, i believe there is no need to use either [ValidateNotNull()] or [ValidateNotNullOrEmpty()] attributes.

        [Parameter(Mandatory=$true,
                   ValueFromPipeline=$true,
                   ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [Alias('HostName','Server','IPAddress','CN','Name')]
        [string[]]$ComputerName
Also, please make sure the property name from Get-ADComputer is nither Null or empty.
July 9th, 2015 3:44pm

did you expanded the property ? 
Get-ADComputer -Filter * | Select-Object -ExpandProperty Name


Free Windows Admin Tool Kit Click here and download it now
July 9th, 2015 4:03pm

Indeed jrv that works but also means my property is now named Name rather than ComputerName.

I was under the impression that because I had alias of Name it would take this down the pipeline and apply it to ComputerName. Is this not correct?

Also "Select -ExpandProperty Name" works.
  • Edited by AJPalmer Thursday, July 09, 2015 4:24 PM
July 9th, 2015 4:22pm

Can you please pipe the Name property to Out-String before calling the function.

Something like this

  function test-call
	 {
	 	param(
					 [Parameter(Mandatory=$true,
				                   ValueFromPipeline=$true,
				                   ValueFromPipelineByPropertyName=$true,
				                   Position=0)]
				        [ValidateNotNull()]
				        [ValidateNotNullOrEmpty()]
				        [Alias('HostName','Server','IPAddress','CN','Name')]
				        [String[]]$ComputerName
	   )
	$ComputerName
	}
	
Get-Content "C:\servers.txt"| out-String |test-call 
 In my case C:\servers.txt has computers list. In your case it would be
Get-ADComputer -Filter * | Select -ExpandProperty Name | Out-String | Test-Call


Free Windows Admin Tool Kit Click here and download it now
July 9th, 2015 5:32pm

Hi AJ,

the only way I was able to make it work (short of writing a .NET Parameter Class) is moving the type validation from the parameter binding into the function process:

function Test-Call
{
	[CmdletBinding()]
	param (
		[Parameter(Mandatory = $true,
				   ValueFromPipeline = $true,
				   Position = 0)]
		[ValidateNotNull()]
		[ValidateNotNullOrEmpty()]
		[Alias('HostName', 'Server', 'IPAddress', 'CN', 'Name')]
		[object]
		$ComputerName
	)
	
	Begin
	{
		function Process-Data
		{
			Param (
				$Name
			)
			
			Write-Host $Name
		}
	}
	Process
	{
		foreach ($Computer in $ComputerName)
		{
			switch ($Computer.GetType().FullName)
			{
				"System.String" { Process-Data $Computer }
				"Microsoft.ActiveDirectory.Management.ADComputer" { Process-Data $Computer.Name }
				default { throw "Invalid Input type!"}
			}
			
		}
	}
}

Cheers,
Fred

July 10th, 2015 2:52am

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics