How do I cast during Select-Object?


I want to return certificate from Get-ChildItem command and having hard time understanding how do I return single instance of X509 certificate instead of array. Currently $cert variable is array of single element. I need it to be done to be output both to Host and assigned to a variable at the same time

Get-ChildItem -Path "Cert:\CurrentUser\My" | where {$_.Subject -eq "CN=CRGRootCert"} | select -First 1 -OutVariable cert

Figured it out, unless there is cleaner way to do that

Get-ChildItem -Path "Cert:\CurrentUser\My"  | where {$_.Subject -eq "CN=CRGRootCert"} | select -First 1 | Set-Variable cert -PassThru

Glad to hear you got it solved! I’m not really the biggest fan of ending a pipeline sequence with Set-Variable, though; it tends to lead to much head-scratching later on as you reread your clever script from three months ago trying to figure where in the blazes you set that variable – oh, it’s at the end of a really long pipeline sequence that scrolls into the sunset, right.

Here is one alternative:

$Certificate = Get-ChildItem -Path "Cert:\CurrentUser\my" |
    Where-Object Subject -eq "CN=CRGRootCert" |
    Select-Object -First 1

(You could put it on one line if you wanted, but I like to break it out so I only have to scroll in one direction to read scripts.)

I would suggest avoid using a default PSDrive provider name as a variable to avoid any issues.

I do this all the time to avoid writing extra stuff to output to the screen, to explicitly avoid unecessary Write-* cmd use and the Set-Variable thing. Well, unless I need color or other special formatting tricks.

($CertData = (Get-ChildItem -Path "Cert:\CurrentUser\My" | 
where {$_.Subject -eq "CN=CRGRootCert"} | 
select -First 1))

It’s called variable Squeezing

Get-Help -Name About_Variables
 Windows PowerShell supports a simplified syntax for showing the
 contents of variables during variable assignment. To do this, wrap
 the variable assignment statement in parentheses.
 Typically, assigning and then displaying variable output requires
 two separate Windows PowerShell commands. But you can consolidate
 the two processes into one statement by using the variable squeezing
 technique. The following examples show the difference.
# Assign the variable
$ProcessList = Get-Process

# Display the variable's contents
# Use variable squeezing to assign and output the variable
($ProcessList = Get-Process) 
$Certificate = Get-ChildItem -Path "Cert:\CurrentUser\my" | Where-Object Subject -eq "CN=CRGRootCert" | Select-Object -First 1

This does not work since it does not output to the screen

Thanks. Learned something new today which was not covered on any PS courses I took.

No worries. Glad it helped.

I deliver PS and many other MOC and custom courses as well. Have done that for years.
Yet, you can’t cover everything in any given course. There is just way to much.

What I always do, is drive folks in my classes to discovery. Just as you’ll never know everything about the city or state you live in, unless you get out and discover all there potentially is to offer (good / bad / indifferent).

In my PS session, MOC or other-wise, before and after I deliver a course. I always start with giving the class this snippet I pulled together over time and resources (which I go back a tweak / update as needed) and spend a good bit of time making them use it throughout the class. It’s the whole, ‘teach a man to fish’ adage. It is something I use daily in my real job and make sure my team does as well. Checking out what you system has and can / cannot do before your try anything approach. Maybe something you can leverage.

# Get parameters, examples, full and Online help for a cmdlet or function

# Get a list of all functions
Get-Command -CommandType Function | 
Out-GridView -PassThru -Title 'Available functions'

# Get a list of all commandlets
Get-Command -CommandType Cmdlet | 
Out-GridView -PassThru -Title 'Available cmdlets'

# Get a list of all functions for the specified name
Get-Command -Name '*ADGroup*' -CommandType Function | 
Out-GridView -PassThru -Title 'Available named functions'

# Get a list of all commandlets for the specified name
Get-Command -Name '*ADGroup*'  -CommandType Cmdlet | 
Out-GridView -PassThru -Title 'Available named cmdlet'

# get function / cmdlet details
(Get-Command -Name Get-ADUser).Parameters
Get-help -Name Get-ADUser -Examples
Get-help -Name Get-ADUser -Full
Get-help -Name Get-ADUser -Online

Get-Help about_*
Get-Help about_Functions

# Find all cmdlets / functions with a target parameter
Get-Command -CommandType Function | 
Where-Object { $_.parameters.keys -match 'credential'} | 
Out-GridView -PassThru -Title 'Available functions which has a specific parameter'

Get-Command -CommandType Cmdlet | 
Where-Object { $_.parameters.keys -match 'credential'} | 
Out-GridView -PassThru -Title 'Results for cmdlets which has a specific parameter'

# Get named aliases 
Get-Alias | 
Out-GridView -PassThru -Title 'Available aliases'

# Get cmdlet / function parameter aliases
(Get-Command Get-ADUser).Parameters.Values | 
where aliases | 
select Name, Aliases | Out-GridView -PassThru -Title 'Alias results for a given cmdlet or function.'

# All Help topics locations
Get-Help about* | Select Name, Synopsis

Get-Help about* | 
  Select-Object -Property Name, Synopsis |
  Out-GridView -Title 'Select Topic' -OutputMode Multiple |
  ForEach-Object {
    Get-Help -Name $_.Name -ShowWindow

explorer "$pshome\$($Host.CurrentCulture.Name)"

# Get any .NET types and their static methods from PowerShell. 
# Enumerate all that are currently loaded into your AppDomain.
[AppDomain]::CurrentDomain.GetAssemblies() | 
foreach { $_.GetTypes() } | 
foreach { $_.GetMethods() } | 
where { $_.IsStatic } | 
select DeclaringType, Name | 
Out-GridView -PassThru -Title '.NET types and their static methods'

# Instantiate the types using new-object and call instance methods. 
# You can use get-member on an instance to get the methods on a type.

# Review source code.
Function Show-CmdletSource


        [string]$CmdletName = (Get-Command -CommandType Cmdlet | 
        Out-GridView -Passthru)

    # Get the DLL is it is a compiled cmdlet
    'Getting DLL if the entered cmdlet name is a compiled cmdlet'
    (Get-Command $CmdletName).DLL 

    If ((Get-Command -Name $CmdletName).ImplementingType)
       # Do nothing 
        # Write-Warning -Message "The entered item is not a cmdlet, but a funciton."
        (Get-Command -Name $CmdletName).ScriptBlock

    'Getting cmdlet details / source code'
    $metadata = New-Object (Get-Command $CmdletName)
    []::Create($MetaData) | 
    out-file "$env:USERPROFILE\Documents\$CmdletName.ps1"

    # Choosing an installed Editor to use.
    # View the cmdlet file
    Start-Process 'Notepad.exe' "$env:USERPROFILE\Documents\$CmdletName.ps1" -Wait

    # Remove the file
    Remove-Item -Path "$env:USERPROFILE\Documents\$CmdletName.ps1"

Function Show-FunctionSource


        [string]$FunctionName = (Get-Command -CommandType Function | 
        Out-GridView -Passthru)

    (Get-Command -Name $FunctionName).ScriptBlock `
    | out-file "$env:USERPROFILE\Documents\$FunctionName.ps1"

    # View the cmdlet file
    Start-Process 'Notepad.exe' "$env:USERPROFILE\Documents\$FunctionName.ps1" -Wait

    # Remove the file
    Remove-Item -Path "$env:USERPROFILE\Documents\$FunctionName.ps1"

# Thoughts on Best Practices

PowerShell scripting best practices

The Unofficial PowerShell Best Practices and Style Guide

Using PSScriptAnalyzer to check your PowerShell code for best practices