Get-Service -Name Spooler | Select-Object -ExcludeProperty Status
Return a Selected.System.ServiceProcess.ServiceController object with all standard properties of System.ServiceProcess.ServiceController except Status.
Returns System.ServiceProcess.ServiceController object with all properties including status.
To get the desired behavior you must use the -Property parameter in conjunction with the -ExcludeProperty parameter, this is explained in the help documentation for select-object as:
"This parameter is effective only when the command also includes the Property parameter."
I don't understand the case where you would want to declare to explicitly include a property, then exclude it again such as:
Get-Service -Name Spooler | Select-Object -Property Status -ExcludeProperty Status
Therefore the convention is to always pass "-Property *" when using the -ExcludeProperty parameter. I would suggest defaulting to -Property * when using the -ExcludeProperty cmdlet, if that would be considered a breaking change, I would suggest throwing an error if -ExcludeProperty is used without -Property indicating that you are missing a mandatory parameter since ExcludeProperty is dependent on -Property.
> $PSVersionTable
Name Value
---- -----
PSVersion 5.0.10586.63
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.10586.63
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
As an additional note, while testing I found that if I used the -Property * pattern on an object with only one property it returned a property named *.
ex:
[pscustomobject]@{Status = 'Running'} | Select-Object -Property * -ExcludeProperty Status
Returns:
*
-
Whereas
[pscustomobject]@{Status = 'Running'} | Select-Object -Property Status -ExcludeProperty Status
returns null as expected.
I just hit this bug today, I exclude properties based on other criteria and I have a scenario where it should exclude all properties but instead of returning nothing I get a property named * with no value.
As a work around I am using | where {$_.psobject.Properties.name -ne "*"} to filter this bad result out.
Ex:
[pscustomobject]@{Thing="thing1"} | Select-Object -Property * -ExcludeProperty thing
Returns:
*
-
Adding the filter:
[pscustomobject]@{Thing="thing1"} | Select-Object -Property * -ExcludeProperty thing | where {$_.psobject.Properties.name -ne "*"}
Returns:
Adding in another property that should pass through with the filter still in place:
[pscustomobject]@{Thing="thing1";thing2="thing2"} |
Select-Object -Property * -ExcludeProperty thing |
where {$_.psobject.Properties.name -ne "*"}
Returns:
thing2
------
thing2
Thanks for the comments Chris, Our solution also involved the PSObject. We ended up just doing something like:
$object = [pscustomobject]@{Thing="thing1"}
$object.PSObject.Properties.Remove('Thing')
$object
Which returns null and can be looped on to remove multiple properties.
I would suggest throwing an error if -ExcludeProperty is used without -Property indicating that you are missing a mandatory parameter since ExcludeProperty is dependent on -Property
This is a breaking change.
the convention is to always pass "-Property *" when using the -ExcludeProperty parameter
As a solution to this issue, it is very simple and non-breaking change.
For second issue I opened #2420
Most helpful comment
As an additional note, while testing I found that if I used the -Property * pattern on an object with only one property it returned a property named *.
ex:
[pscustomobject]@{Status = 'Running'} | Select-Object -Property * -ExcludeProperty StatusReturns:
*-Whereas
[pscustomobject]@{Status = 'Running'} | Select-Object -Property Status -ExcludeProperty Statusreturns null as expected.