Author Posts

July 10, 2014 at 9:12 am

I have a script that I'm trying to use AD computer objects to populate a computername parameter. The script is called servicecheck.ps1 and it's designed to see if a service is present, not present, or if computers are unreachable.

[cmdletbinding()]
param (
[parameter(mandatory=$true)][string]$servicename,

[parameter(mandatory=$true,valuefrompipelinebypropertyname=$true)]
[alias('Name')][string[]]$computername
)
begin {}
process{
foreach ($single in $computername) {
Try {
invoke-command -ComputerName $single -ScriptBlock {param($rservicename) get-service `
-name $rservicename} -ArgumentList $servicename -ErrorAction stop | out-null
$success += "$single`r`n"
} catch {
if ($_.exception -like "*cannot find any service*") {$serviceerror += "$single`r`n"}
if ($_.exception -like "*connecting to remote*") {$pserror += "$single`r`n"}
}
}
}
end {
if ($success -eq $null) {$success = "None`r`n"}
if ($serviceerror -eq $null) {$serviceerror = "None`r`n"}
if ($pserror -eq $null) {$pserror = "None`r`n"}

write-output "Computers with $servicename present"
write-output "$success`r"
write-output "Computers without $servicename present"
write-output "$serviceerror`r"
write-output "Computers that couldn't be contacted"
write-output "$pserror"
}

When I try to run the command using the following line: Get-ADComputer -Filter * | .\servicecheck.ps1 -servicename bits
I get the following error for each computer that is fetched from get-adcomputer.

E:\servicecheck.ps1 : Cannot bind argument to parameter 'computername' because it is an empty array.
At line:1 char:28
+ Get-ADComputer -Filter * | .\servicecheck.ps1 -servicename bits
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (CN=LON-DC1,OU=D...C=Adatum,DC=com:PSObject) [servicecheck.ps1], ParameterB
indingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorEmptyArrayNotAllowed,servicecheck.ps1

When I run the script like this: Get-ADComputer -Filter * | select @{n='name';e={$_.name}} | .\servicecheck.ps1 -servicename bits
It works fine. I don't want to have to resort to using a calculated property so am wondering why the name property in the adcomputer object isn't matching up bypropertyname with the computername property I've setup with the alias of 'name'

Thanks in advance for any insight anyone might have

July 10, 2014 at 10:16 am

If this :

 Get-ADComputer -Filter * | select @{n='name';e={$_.name}} | .\servicecheck.ps1 -servicename bits 

it means that the alias "Name" for your $computername parameter is not the problem.

The problem comes most likely from the objects which are in the pipeline when you run servicecheck.ps1.

Maybe, the objects in the pipeline after "Get-ADComputer -Filter *" don't actually present the "Name" property.
If this is the case, the following should solve your issue :

 Get-ADComputer -Filter * -Property * | .\servicecheck.ps1 -servicename bits 

July 10, 2014 at 10:26 am

That's an annoying bit of behavior with the Active Directory cmdlets. They don't play very well with the pipeline, but you can fix it by sticking Select-Object between the AD cmdlet and the command that's to receive input:

Get-ADComputer -Filter * | Select-Object * | .\servicecheck.ps1 -servicename bits

July 10, 2014 at 12:05 pm

What was driving me nuts is the name property is one of the ten properties that get-adcomputer retrieves by default.

Dave, thanks for the tip that the AD cmdlets don't behave normally. When I tried inserting the select * in between my script worked. Not ideal but it lets me know the parameters in my script are correct.

July 10, 2014 at 2:43 pm

Just another note that if you only need the Name property, you will have some better performance just getting the required properties.

Get-ADComputer -Filter Name | Select-Object Name | .\servicecheck.ps1 -servicename bits