How do I cast during Select-Object?

This topic contains 6 replies, has 3 voices, and was last updated by  postanote 2 weeks, 1 day ago.

  • Author
    Posts
  • #103820

    GS
    Participant

    Hello,

    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
  • #103825

    GS
    Participant

    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
  • #103838

    Joel Sallow
    Participant

    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.)

    • #103847

      GS
      Participant

      $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

  • #103844

    postanote
    Participant

    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
    

    VARIABLE SQUEEZING

    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
    $ProcessList
            
    # Use variable squeezing to assign and output the variable
    ($ProcessList = Get-Process) 
    
    • #103850

      GS
      Participant

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

    • #103942

      postanote
      Participant

      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
      {
          [CmdletBinding()]
      
          [Alias('scs')]
      
          Param
          (
              [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 
          }
          Else
          {
              # 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 system.management.automation.commandmetadata (Get-Command $CmdletName)
          [System.management.automation.proxycommand]::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
      {
          [CmdletBinding()]
      
          [Alias('sfs')]
      
          Param
          (
              [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
      'https://blogs.technet.microsoft.com/pstips/2014/06/17/powershell-scripting-best-practices'
      
      The Unofficial PowerShell Best Practices and Style Guide
      https://blogs.technet.microsoft.com/pstips/2014/06/17/powershell-scripting-best-practices
      
      Using PSScriptAnalyzer to check your PowerShell code for best practices
      'http://mikefrobbins.com/2015/11/19/using-psscriptanalyzer-to-check-your-powershell-code-for-best-practices'
      

You must be logged in to reply to this topic.