Advanced Windows PowerShell Scripting Video Training

Advanced Windows PowerShell Scripting Video Training
Advanced Windows PowerShell Scripting Video Training

Monday, September 26, 2016

When the Cmdlet is Bad

This is post 7 of 7 in this series.

Take a look at this code and ask yourself “Will I be able to list all services running on all clients in my domain?”

PS C:\> "DC1", "SVR1", "SVR2" | Get-Service

Well, let’s take a look at the help file for Get-Service and see is any parameters accept pipeline input ByValue. I shortened the list to the only two parameters that do.

Get-Help Get-Service -Parameter *

-InputObject []
    Specifies ServiceController objects representing the services to be retrieved. Enter a
    variable that contains the objects, or type a command or expression that gets the
    objects. You can also pipe a service object to this cmdlet.
   
    Required?                    false
    Position?                    named
    Default value                none
    Accept pipeline input?       true (ByValue)
    Accept wildcard characters?  false
   

-Name []
    Specifies the service names of services to be retrieved. Wildcards are permitted. By
    default, this cmdlet gets all of the services on the computer.
   
    Required?                    false
    Position?                    1
    Default value                none
    Accept pipeline input?       true(ByValue,ByPropertyName)
    Accept wildcard characters?  false

We can also see that the -ComputerName­ parameter accepts pipeline input, but ByPropertyName.  

-ComputerName []
    Gets the services running on the specified computers. The default is the local
    computer.
   
    Type the NetBIOS name, an IP address, or a fully qualified domain name (FQDN) of a
    remote computer. To specify the local computer, type the computer name, a dot (.), or
    localhost.
   
    This parameter does not rely on Windows PowerShell remoting. You can use the
    ComputerName parameter of Get-Service even if your computer is not configured to run
    remote commands.
   
    Required?                    false
    Position?                    named
    Default value                none
    Accept pipeline input?       true (ByPropertyName)
    Accept wildcard characters?  false

Our goal is to pass the names of computers to Get-Service and then recover the services running on those nodes.  Let’s give this a try and see what happens.

PS C:\> "DC1", "SVR1", "SVR2" | Get-Service
Get-Service : Cannot find any service with service name 'DC1'.
At line:1 char:25
+ "DC1", "SVR1", "SVR2" | Get-Service
+                         ~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (DC1:String) [Get-Service], ServiceCommandException
    + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand

Get-Service : Cannot find any service with service name 'SVR1'.
At line:1 char:25
+ "DC1", "SVR1", "SVR2" | Get-Service
+                         ~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (SVR1:String) [Get-Service], ServiceCommandException
    + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand

Get-Service : Cannot find any service with service name 'SVR2'.
At line:1 char:25
+ "DC1", "SVR1", "SVR2" | Get-Service
+                         ~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (SVR2:String) [Get-Service], ServiceCommandException
    + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand

Here we passed three valid, online computer names to Get-Service via the PowerShell pipeline.  The problem is that we want these services to bind to the –ComputerName parameter, which we already know they will not.  Read one of the three error messages.  Get-Service is actually looking for services named DC1, SVR1 and SVR2.  What?  Remember, the –Name parameter accepts strings and that is what we sent it.  OK, let’s create an object that has a ComputerName property and pipe it to Get-Service and attempt to use the ByPropertyName passing that the –ComputerName parameter is advertising.

First, we are going to grab the ActiveDirectory computer object from the database.  We are going to specify only the computer name DC1 to keep this simple.

Get-ADComputer –Filter {name -eq "DC1"}

DistinguishedName : CN=DC1,OU=Domain Controllers,DC=PowerIT,DC=com
DNSHostName       : DC1.PowerIT.com
Enabled           : True
Name              : DC1
ObjectClass       : computer
ObjectGUID        : 14313c03-ecb8-4126-b180-89619742922a
SamAccountName    : DC1$
SID               : S-1-5-21-31908143-1805627216-1122469826-1000
UserPrincipalName : 

As you can see, this object does not have property call ComputerName so we cannot pass it to Get-Service. We can send it to SelectObject and rename the Name property to ComputerName.

Get-ADComputer –Filter {name -eq "DC1"} |
Select-Object -Property *, @{Name='ComputerName';Expression={$PSItem.Name}}

DistinguishedName  : CN=DC1,OU=Domain Controllers,DC=PowerIT,DC=com
DNSHostName        : DC1.PowerIT.com
Enabled            : True
Name               : DC1
ObjectClass        : computer
ObjectGUID         : 14313c03-ecb8-4126-b180-89619742922a
SamAccountName     : DC1$
SID                : S-1-5-21-31908143-1805627216-1122469826-1000
UserPrincipalName  :
PropertyNames      : {DistinguishedName, DNSHostName, Enabled, Name...}
AddedProperties    : {}
RemovedProperties  : {}
ModifiedProperties : {}
PropertyCount      : 9
ComputerName       : DC1

You can see from the output that we have a new property call ComputerName and its value came from the objects Name property.  Now we have met the criteria for passing the computer name DC1 to the –ComputerName parameter of Get-Service, let’s give it a try.

Get-ADComputer –Filter {name -eq "DC1"} |
Select-Object -Property *, @{Name='ComputerName';Expression={$PSItem.Name}} |
Get-Service

And here is the result:
Get-Service : Cannot find any service with service name 'DC1'.
At line:3 char:1
+ Get-Service
+ ~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (DC1:String) [Get-Service], ServiceCommandException
    + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand

Um… What?  The Get-Service cmdlet is once again looking for a service called DC1 instead of binding DC1 as the argument for –ComputerName.  This is the tricky part about ByValue. It can cause some odd behaviors.
I have looked at a lot of discussions on why this is happening.  So far, there are a lot of theories. One work around is to explicitly ask for all services by adding –Name *. Take a look.

Get-ADComputer –Filter {name -eq "DC1"} |
Select-Object -Property *, @{Name='ComputerName';Expression={$PSItem.Name}} |
Get-Service -Name *

Status   Name               DisplayName                          
------   ----               -----------                          
Running  ADWS               Active Directory Web Services        
Stopped  AJRouter           AllJoyn Router Service               
Stopped  ALG                Application Layer Gateway Service 

There is a rule in PowerShell piping that you cannot pass input to a parameter and call it at the same time.  In the example below, we are piping the string “Bits” to Get-Service. This normally works, but we are also explicitly using the –Name parameter of Get-Service at the same time.

PS C:\> "Bits" | Get-Service -Name "Bits"
Get-Service : The input object cannot be bound to any parameters for the command either because the command does not take
pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
At line:1 char:10
+ "Bits" | Get-Service -Name "Bits"
+          ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (Bits:String) [Get-Service], ParameterBindingException
    + FullyQualifiedErrorId : InputObjectNotBound,Microsoft.PowerShell.Commands.GetServiceCommand

This is a no go.  In the above example that worked, my best guess is that since ByValue is tried first and we are not explicitly using the –Name parameter, the ByPropertyName parameter of –ComputerName now has a chance to accept the pipeline input.

To put this theory to the test, I utilized Trace-Command.  Get ready, there is a lot of information coming. I added my notes to the output with a dark green background that looks like this:

>>>> This is where Get-Service starts <<<<

Everything else came from the execution of Trace-Command.

Trace-Command -name ParameterBinding -PSHost -Expression {    Get-ADComputer –Filter {name -eq "DC1"} |
       Select @{Name='ComputerName';Expression={$PSItem.Name}} |
       Get-Service}

DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Get-ADComputer]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Get-ADComputer]
DEBUG: ParameterBinding Information: 0 : BIND cmd line args to DYNAMIC parameters.
DEBUG: ParameterBinding Information: 0 :     DYNAMIC parameter object: [Microsoft.ActiveDirectory.Management.Commands.GetADCompu
terParameterSet]
DEBUG: ParameterBinding Information: 0 :     BIND NAMED args to DYNAMIC parameters
DEBUG: ParameterBinding Information: 0 :         BIND arg [name -eq "DC1"] to parameter [Filter]
DEBUG: ParameterBinding Information: 0 :             Executing DATA GENERATION metadata: [Microsoft.ActiveDirectory.Management.C
ommands.TransformFilterAttribute]
DEBUG: ParameterBinding Information: 0 :                 result returned from DATA GENERATION: name -eq "DC1"
DEBUG: ParameterBinding Information: 0 :             COERCE arg to [System.String]
DEBUG: ParameterBinding Information: 0 :                 Trying to convert argument value from System.Management.Automation.Scri
ptBlock to System.String
DEBUG: ParameterBinding Information: 0 :                 CONVERT arg type to param type using LanguagePrimitives.ConvertTo
DEBUG: ParameterBinding Information: 0 :                 CONVERT SUCCESSFUL using LanguagePrimitives.ConvertTo: [name -eq "DC1"]
DEBUG: ParameterBinding Information: 0 :             Executing VALIDATION metadata: [System.Management.Automation.ValidateNotNul
lOrEmptyAttribute]
DEBUG: ParameterBinding Information: 0 :             BIND arg [name -eq "DC1"] to param [Filter] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND POSITIONAL args to DYNAMIC parameters
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Get-ADComputer]
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Select-Object]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Select-Object]
DEBUG: ParameterBinding Information: 0 :     BIND arg [System.Collections.Hashtable] to parameter [Property]
DEBUG: ParameterBinding Information: 0 :         Binding collection parameter Property: argument type [Hashtable], parameter typ
e [System.Object[]], collection type Array, element type [System.Object], no coerceElementType
DEBUG: ParameterBinding Information: 0 :         Creating array with element type [System.Object] and 1 elements
DEBUG: ParameterBinding Information: 0 :         Argument type Hashtable is not IList, treating this as scalar
DEBUG: ParameterBinding Information: 0 :         Adding scalar element of type Hashtable to array position 0
DEBUG: ParameterBinding Information: 0 :         BIND arg [System.Object[]] to param [Property] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Select-Object]
>>>> This is where Get-Service starts <<<<
DEBUG: ParameterBinding Information: 0 : BIND NAMED cmd line args [Get-Service]
DEBUG: ParameterBinding Information: 0 : BIND POSITIONAL cmd line args [Get-Service]
DEBUG: ParameterBinding Information: 0 : MANDATORY PARAMETER CHECK on cmdlet [Get-Service]
DEBUG: ParameterBinding Information: 0 : CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 :     BIND PIPELINE object to parameters: [Select-Object]
DEBUG: ParameterBinding Information: 0 :         PIPELINE object TYPE = [Microsoft.ActiveDirectory.Management.ADComputer]
DEBUG: ParameterBinding Information: 0 :         RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :         Parameter [InputObject] PIPELINE INPUT ValueFromPipeline NO COERCION
DEBUG: ParameterBinding Information: 0 :         BIND arg [CN=DC1,OU=Domain Controllers,DC=PowerIT,DC=com] to parameter [InputOb
ject]
DEBUG: ParameterBinding Information: 0 :             BIND arg [CN=DC1,OU=Domain Controllers,DC=PowerIT,DC=com] to param [InputOb
ject] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     MANDATORY PARAMETER CHECK on cmdlet [Select-Object]
DEBUG: ParameterBinding Information: 0 :     BIND PIPELINE object to parameters: [Get-Service]
DEBUG: ParameterBinding Information: 0 :         PIPELINE object TYPE = [Selected.Microsoft.ActiveDirectory.Management.ADCompute
r]
DEBUG: ParameterBinding Information: 0 :         RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :         Parameter [Name] PIPELINE INPUT ValueFromPipeline NO COERCION

>>>> Here is the problem.  <<<<

DEBUG: ParameterBinding Information: 0 :         BIND arg [@{ComputerName=DC1}] to parameter [Name]
DEBUG: ParameterBinding Information: 0 :             Binding collection parameter Name: argument type [PSObject], parameter type
 [System.String[]], collection type Array, element type [System.String], no coerceElementType
DEBUG: ParameterBinding Information: 0 :             Creating array with element type [System.String] and 1 elements
DEBUG: ParameterBinding Information: 0 :             Argument type PSObject is not IList, treating this as scalar
DEBUG: ParameterBinding Information: 0 :             BIND arg [@{ComputerName=DC1}] to param [Name] SKIPPED
DEBUG: ParameterBinding Information: 0 :         Parameter [ComputerName] PIPELINE INPUT ValueFromPipelineByPropertyName NO COER
CION

>>>> An attempt is made to bind DC1 to -ComputerName.  <<<<

DEBUG: ParameterBinding Information: 0 :         BIND arg [DC1] to parameter [ComputerName]
DEBUG: ParameterBinding Information: 0 :             Binding collection parameter ComputerName: argument type [String], paramete
r type [System.String[]], collection type Array, element type [System.String], no coerceElementType
DEBUG: ParameterBinding Information: 0 :             Creating array with element type [System.String] and 1 elements
DEBUG: ParameterBinding Information: 0 :             Argument type String is not IList, treating this as scalar
DEBUG: ParameterBinding Information: 0 :             Adding scalar element of type String to array position 0
DEBUG: ParameterBinding Information: 0 :             Executing VALIDATION metadata: [System.Management.Automation.ValidateNotNul
lOrEmptyAttribute]

>>>> It says that it is successful.  <<<<

DEBUG: ParameterBinding Information: 0 :             BIND arg [System.String[]] to param [ComputerName] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :         Parameter [Name] PIPELINE INPUT ValueFromPipelineByPropertyName NO COERCION
DEBUG: ParameterBinding Information: 0 :         Parameter [Name] PIPELINE INPUT ValueFromPipeline WITH COERCION

>>>> But it looks like it is also binding DC1 to the –Name parameter.  <<<<

DEBUG: ParameterBinding Information: 0 :         BIND arg [@{ComputerName=DC1}] to parameter [Name]
DEBUG: ParameterBinding Information: 0 :             COERCE arg to [System.String[]]
DEBUG: ParameterBinding Information: 0 :                 Trying to convert argument value from System.Management.Automation.PSOb
ject to System.String[]
DEBUG: ParameterBinding Information: 0 :                 ENCODING arg into collection
DEBUG: ParameterBinding Information: 0 :                 Binding collection parameter Name: argument type [PSObject], parameter
type [System.String[]], collection type Array, element type [System.String], coerceElementType
DEBUG: ParameterBinding Information: 0 :                 Creating array with element type [System.String] and 1 elements
DEBUG: ParameterBinding Information: 0 :                 Argument type PSObject is not IList, treating this as scalar
DEBUG: ParameterBinding Information: 0 :                 COERCE arg to [System.String]
DEBUG: ParameterBinding Information: 0 :                     Trying to convert argument value from System.Management.Automation.
PSObject to System.String
DEBUG: ParameterBinding Information: 0 :                     CONVERT arg type to param type using LanguagePrimitives.ConvertTo
DEBUG: ParameterBinding Information: 0 :                     CONVERT SUCCESSFUL using LanguagePrimitives.ConvertTo: [@{ComputerN
ame=DC1}]

>>>> Here it is binding DC1 to the first positional parameter which is -Name  <<<<

DEBUG: ParameterBinding Information: 0 :                 Adding scalar element of type String to array position 0
DEBUG: ParameterBinding Information: 0 :             BIND arg [System.String[]] to param [Name] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     MANDATORY PARAMETER CHECK on cmdlet [Get-Service]
DEBUG: ParameterBinding Information: 0 :     BIND PIPELINE object to parameters: [Out-Default]
DEBUG: ParameterBinding Information: 0 :         PIPELINE object TYPE = [System.Management.Automation.ErrorRecord]
DEBUG: ParameterBinding Information: 0 :         RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :         Parameter [InputObject] PIPELINE INPUT ValueFromPipeline NO COERCION
DEBUG: ParameterBinding Information: 0 :         BIND arg [Cannot find any service with service name '@{ComputerName=DC1}'.] to
parameter [InputObject]
DEBUG: ParameterBinding Information: 0 :             BIND arg [Cannot find any service with service name '@{ComputerName=DC1}'.]
 to param [InputObject] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     MANDATORY PARAMETER CHECK on cmdlet [Out-Default]
DEBUG: ParameterBinding Information: 0 :     BIND NAMED cmd line args [Out-LineOutput]
DEBUG: ParameterBinding Information: 0 :         BIND arg [Microsoft.PowerShell.Commands.Internal.Format.ConsoleLineOutput] to p
arameter [LineOutput]
DEBUG: ParameterBinding Information: 0 :             COERCE arg to [System.Object]
DEBUG: ParameterBinding Information: 0 :                 Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :             BIND arg [Microsoft.PowerShell.Commands.Internal.Format.ConsoleLineOutput]
to param [LineOutput] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND POSITIONAL cmd line args [Out-LineOutput]
DEBUG: ParameterBinding Information: 0 :     MANDATORY PARAMETER CHECK on cmdlet [Out-LineOutput]
DEBUG: ParameterBinding Information: 0 :     CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 :     BIND PIPELINE object to parameters: [Out-LineOutput]
DEBUG: ParameterBinding Information: 0 :         PIPELINE object TYPE = [System.Management.Automation.ErrorRecord]
DEBUG: ParameterBinding Information: 0 :         RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :         Parameter [InputObject] PIPELINE INPUT ValueFromPipeline NO COERCION
DEBUG: ParameterBinding Information: 0 :         BIND arg [Cannot find any service with service name '@{ComputerName=DC1}'.] to
parameter [InputObject]
DEBUG: ParameterBinding Information: 0 :             BIND arg [Cannot find any service with service name '@{ComputerName=DC1}'.]
 to param [InputObject] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     MANDATORY PARAMETER CHECK on cmdlet [out-lineoutput]
DEBUG: ParameterBinding Information: 0 :     BIND NAMED cmd line args [Format-Default]
DEBUG: ParameterBinding Information: 0 :     BIND POSITIONAL cmd line args [Format-Default]
DEBUG: ParameterBinding Information: 0 :     MANDATORY PARAMETER CHECK on cmdlet [Format-Default]
DEBUG: ParameterBinding Information: 0 :     CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 :     BIND PIPELINE object to parameters: [Format-Default]
DEBUG: ParameterBinding Information: 0 :         PIPELINE object TYPE = [System.Management.Automation.ErrorRecord]
DEBUG: ParameterBinding Information: 0 :         RESTORING pipeline parameter's original values
DEBUG: ParameterBinding Information: 0 :         Parameter [InputObject] PIPELINE INPUT ValueFromPipeline NO COERCION
DEBUG: ParameterBinding Information: 0 :         BIND arg [Cannot find any service with service name '@{ComputerName=DC1}'.] to
parameter [InputObject]
DEBUG: ParameterBinding Information: 0 :             BIND arg [Cannot find any service with service name '@{ComputerName=DC1}'.]
 to param [InputObject] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     MANDATORY PARAMETER CHECK on cmdlet [format-default]
DEBUG: ParameterBinding Information: 0 :     BIND NAMED cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :         BIND arg [1] to parameter [Version]
DEBUG: ParameterBinding Information: 0 :             Executing DATA GENERATION metadata: [Microsoft.PowerShell.Commands.SetStric
tModeCommand+ArgumentToVersionTransformationAttribute]
DEBUG: ParameterBinding Information: 0 :                 result returned from DATA GENERATION: 1.0
DEBUG: ParameterBinding Information: 0 :             COERCE arg to [System.Version]
DEBUG: ParameterBinding Information: 0 :                 Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :             Executing VALIDATION metadata: [Microsoft.PowerShell.Commands.SetStrictMode
Command+ValidateVersionAttribute]
DEBUG: ParameterBinding Information: 0 :             BIND arg [1.0] to param [Version] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND POSITIONAL cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     MANDATORY PARAMETER CHECK on cmdlet [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 :     CALLING EndProcessing
DEBUG: ParameterBinding Information: 0 :     BIND NAMED cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :         BIND arg [1] to parameter [Version]
DEBUG: ParameterBinding Information: 0 :             Executing DATA GENERATION metadata: [Microsoft.PowerShell.Commands.SetStric
tModeCommand+ArgumentToVersionTransformationAttribute]
DEBUG: ParameterBinding Information: 0 :                 result returned from DATA GENERATION: 1.0
DEBUG: ParameterBinding Information: 0 :             COERCE arg to [System.Version]
DEBUG: ParameterBinding Information: 0 :                 Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :             Executing VALIDATION metadata: [Microsoft.PowerShell.Commands.SetStrictMode
Command+ValidateVersionAttribute]
DEBUG: ParameterBinding Information: 0 :             BIND arg [1.0] to param [Version] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND POSITIONAL cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     MANDATORY PARAMETER CHECK on cmdlet [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 :     CALLING EndProcessing
DEBUG: ParameterBinding Information: 0 :     BIND NAMED cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :         BIND arg [1] to parameter [Version]
DEBUG: ParameterBinding Information: 0 :             Executing DATA GENERATION metadata: [Microsoft.PowerShell.Commands.SetStric
tModeCommand+ArgumentToVersionTransformationAttribute]
DEBUG: ParameterBinding Information: 0 :                 result returned from DATA GENERATION: 1.0
DEBUG: ParameterBinding Information: 0 :             COERCE arg to [System.Version]
DEBUG: ParameterBinding Information: 0 :                 Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :             Executing VALIDATION metadata: [Microsoft.PowerShell.Commands.SetStrictMode
Command+ValidateVersionAttribute]
DEBUG: ParameterBinding Information: 0 :             BIND arg [1.0] to param [Version] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND POSITIONAL cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     MANDATORY PARAMETER CHECK on cmdlet [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 :     CALLING EndProcessing
DEBUG: ParameterBinding Information: 0 :     BIND NAMED cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :         BIND arg [1] to parameter [Version]
DEBUG: ParameterBinding Information: 0 :             Executing DATA GENERATION metadata: [Microsoft.PowerShell.Commands.SetStric
tModeCommand+ArgumentToVersionTransformationAttribute]
DEBUG: ParameterBinding Information: 0 :                 result returned from DATA GENERATION: 1.0
DEBUG: ParameterBinding Information: 0 :             COERCE arg to [System.Version]
DEBUG: ParameterBinding Information: 0 :                 Parameter and arg types the same, no coercion is needed.
DEBUG: ParameterBinding Information: 0 :             Executing VALIDATION metadata: [Microsoft.PowerShell.Commands.SetStrictMode
Command+ValidateVersionAttribute]
DEBUG: ParameterBinding Information: 0 :             BIND arg [1.0] to param [Version] SUCCESSFUL
DEBUG: ParameterBinding Information: 0 :     BIND POSITIONAL cmd line args [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     MANDATORY PARAMETER CHECK on cmdlet [Set-StrictMode]
DEBUG: ParameterBinding Information: 0 :     CALLING BeginProcessing
DEBUG: ParameterBinding Information: 0 :     CALLING EndProcessing
Get-Service : Cannot find any service with service name '@{ComputerName=DC1}'.
At line:3 char:3
+      Get-Service}
+      ~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (@{ComputerName=DC1}:String) [Get-Service], ServiceCommandException
    + FullyQualifiedErrorId : NoServiceFoundForGivenName,Microsoft.PowerShell.Commands.GetServiceCommand

DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing
DEBUG: ParameterBinding Information: 0 : CALLING EndProcessing



Again, a lot of information. In short I can only assume that there is a coding error in either how PowerShell handles ByValue passing or the programmer of the cmdlet did not do a thorough debugging. This is an example as to why you should always test your code thoroughly before making a public release.

No comments: