• Getting Available Video Resolutions

    WMI can return a list of available video resolutions for your video adapter:

     
    PS> Get-CimInstance -ClassName CIM_VideoControllerResolution |
     Select-Object -Property SettingID
    
    SettingID                                              
    ---------                                              
    640 x 480 x 4294967296 colors @ 60 Hertz               
    640 x 480 x 4294967296 colors @ 67 Hertz               
    640 x 480 x 4294967296…
    • 6 Apr 2020
  • Be Careful with Some Commands

    Here are three commands often found in PowerShell scripts that you should be careful about because they can have severe side effects:

    exit
    “exit” is not really a command but rather part of the language. It exits PowerShell immediately, and optionally you can submit a number which will be the “error level” that callers can query.

    Use “exit” only when you really want to exit PowerShell. Do not use…

    • 2 Apr 2020
  • Dealing with Out-GridView Bug

    Out-GridView can serve as a universal selection dialog when you add the -PassThru parameter. The one-liner below stops all services you select in the grid view window (well, not really; you can play safely until you remove -WhatIf):

     
    Get-Service | Out-GridView -Title 'Select Service' -PassThru | Stop-Service -WhatIf  
     

    However, there is a long-standing bug in Out-GridView: while information is pumped into the…

    • 31 Mar 2020
  • Exploring WMI with PowerShell

    The Win32_LogicalDevice WMI class represents all logic devices available in a computer, and by querying this “superclass”, you get back all the specialized individual classes. This is a simple way of finding out what kind of information WMI can get you, and what the names of WMI classes are:

    Get-CimInstance -ClassName CIM_LogicalDevice | 
        Select-Object -Property Name, CreationClassName, DeviceID, Syst…
    • 27 Mar 2020
  • Adding New PowerShell Commands with Carbon

    Carbon is one of the most popular free PowerShell modules available from the PowerShell Gallery. Similar to a swiss army knife, it comes with a variety of helper functions. To install it, run this:

     
    PS> Install-Module -Name Carbon -Scope CurrentUser -Force
     

    Apparently, the owner of this module has added useful functionality whenever it was needed. This is all you need to test whether your PowerShell currently is…

    • 25 Mar 2020
  • Managing Updates with PSWindowsUpdate

    There are many useful PowerShell modules available from the PowerShell Gallery. One helps you managing updates. To download and install it, run:

     
    PS> Install-Module -Name PSWindowsUpdate -Scope CurrentUser -Force
     

    It adds a list of new commands related to Windows Update:

     
    PS> Get-Command -Module PSWindowsUpdate 
    
    CommandType Name                    Version Source         
    ----------- ----                    ---…
    • 23 Mar 2020
  • Dynamic Argument Completion (Part 5)

    In our previous tip we looked at sophisticated completion code that completed application paths. Collecting the completion values could take some time and had the potential of timing out IntelliSense. For completion values that are unlikely to change, it is much better to calculate the values once and then use cached values.

    This way, installing the completers will cost a second or two, but after that you enjoy rapid…

    • 19 Mar 2020
  • Dynamic Argument Completion (Part 4)

    In the previous tip we explained how you can use [ArgumentCompleter] to add powerful argument completers for parameters. There are limitations though:

    • When the completion code becomes complex, your code becomes hard to read
    • You cannot add argument completion to existing commands. The [ArgumentCompleter] attribute only works with your own functions

    In reality, though, the attribute is just one of two ways to add argument…

    • 17 Mar 2020
  • Dynamic Argument Completion (Part 3)

    With the discoveries in our past tips, let’s compose a useful completion code that suggests all available programs you can launch:

    function Start-Software {
        param(
            [Parameter(Mandatory)]
            [ArgumentCompleter({
            
           
    # get registered applications from registry     
    $key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\*", 
        "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion…
    • 13 Mar 2020
  • Dynamic Argument Completion (Part 2)

    In our previous tip we looked at [ArgumentCompleter] and how this attribute can add clever code to parameters that provides auto-completion values for your arguments. AutoCompletion can do even more: you can submit different values for the IntelliSense menu, and for the actual completion.

    Check this code:

    function Get-OU {
        param(
            [Parameter(Mandatory)]
            [ArgumentCompleter({
            
            [Management…
    • 11 Mar 2020
  • Dynamic Argument Completion (Part 1)

    In previous tips we explained various ways of adding argument completers to your parameters. One approach used the [ArgumentCompleter] attribute and looked like this: As you can see, it’s solely a matter of refining the completion code: when the file name contains a space, the expression is placed inside quotes, else it isn’t. If you wanted the completer to only return files and omit folders, add the -File parameter to…

    • 9 Mar 2020
  • Listing Installed Applications (Part 2)

    In the previous tip we read the registry to find out paths to applications you can launch. This approach worked well but had two flaws: first, the list did not include the friendly names for the applications, and second, the list was not complete. Only programs who chose to register themselves were listed.

    Let’s get a complete list of applications and use three tricks to overcome the limitations:

    • Use a generic…
    • 5 Mar 2020
  • Listing Installed Applications (Part 1)

    Ever wondered what the path is to launch a given application? The Windows registry has a key that stores such information:

      $key = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\*", 
            "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\*"
    
     $lookup = Get-ItemProperty -Path $key | 
     Select-Object -ExpandProperty '(Default)' -ErrorAction Ignore |
     Where-Object { $_
    • 3 Mar 2020
  • Secret Dynamic Argument Completer

    In the previous tip we introduced the lesser-known “ArgumentCompletion” attribute that can provide IntelliSense-like autocompletion to parameters. This attribute can do way more than that, though. Previously, we introduced this code:

    function Get-Vendor {
        param(
            [Parameter(Mandatory)]
            [ArgumentCompleter({'Microsoft','Amazon','Google'})]
            [string]
            $Vendor
        )
    
        "Chosen…
    • 28 Feb 2020
  • Creating Colorful Console Hardcopies

    If you’d like to hardcopy the content of a PowerShell console, you can copy and select the text, but this messes up colors and formatting.

    A better way is reading the console screen buffer, and composing HTML documents. These HTML documents can then be copied and pasted into Word and other targets, and keep formatting and colors

    The code below is certainly not yet perfect but illustrates the path to take:

    funct…
    • 26 Feb 2020
  • Understanding $ErrorView

    When PowerShell encounters a problem, it displays a rather lengthy error message:

     
    PS> 1/0
    Attempted to divide by zero.
    At line:1 char:1
    + 1/0
    + ~~~
        + CategoryInfo          : NotSpecified: (:) [], RuntimeException
        + FullyQualifiedErrorId : RuntimeException
     

    In real life, you often just need the first line, and as early as in 2006, the PowerShell team added a preference variable called $ErrorView that can…

    • 24 Feb 2020
  • IntelliSense for Parameters (Part 4)

    Wouldn’t it be nice if parameters would suggest valid arguments for the user? Sometimes they do. When you type below command and press a SPACE after -LogName, PowerShell ISE and Visual Studio Code pop up an IntelliSense menu with all log files you can dump:

     
    PS> Get-EventLog -LogName   
     

    If no automatic Intellisense pops up (i.e. in the PowerShell console), you can press TAB for auto completion, or CTRL+SPACE…

    • 20 Feb 2020
  • IntelliSense for Parameters (Part 3)

    Wouldn’t it be nice if parameters would suggest valid arguments for the user? Sometimes they do. When you type below command and press a SPACE after -LogName, PowerShell ISE and Visual Studio Code pop up an IntelliSense menu with all log files you can dump:

     
    PS> Get-EventLog -LogName  
     

    If no automatic IntelliSense pops up (i.e. in the PowerShell console), you can press TAB for auto completion, or CTRL+SPACE…

    • 18 Feb 2020
  • IntelliSense for Parameters (Part 2)

    Wouldn’t it be nice if parameters would suggest valid arguments for the user? Sometimes they do. When you type below command and press a SPACE after -LogName, PowerShell ISE and Visual Studio Code pop up an IntelliSense menu with all log files you can dump:

     
     PS> Get-EventLog -LogName
     

    If no automatic IntelliSense pops up (i.e. in the PowerShell console), you can press TAB for auto completion, or CTRL+SPACE…

    • 14 Feb 2020
  • IntelliSense for Parameters (Part 1)

    Wouldn’t it be nice if parameters would suggest valid arguments for the user? Sometimes they do. When you type below command and press a SPACE after -LogName, PowerShell ISE and Visual Studio Code pop up an IntelliSense menu with all log files you can dump:

     
    PS> Get-EventLog -LogName 
     

    If no automatic IntelliSense pops up (i.e. in the PowerShell console), you can press TAB for auto completion, or CTRL+SPACE…

    • 12 Feb 2020
  • Separating IPv4 and IPv6

    Let’s assume you want to return IP addresses from all network cards but separate them by address type. Here is an approach that uses solely Select-Object:

    function Get-IPAddress
    {
      Get-CimInstance -ClassName Win32_NetworkAdapterConfiguration |
      Where-Object { $_.IPEnabled -eq $true } |
      # add two new properties for IPv4 and IPv6 at the end
      Select-Object -Property Description, MacAddress, IPAddress, IPAddre…
    • 10 Feb 2020
  • Installing and Test-Driving Windows Terminal

    Windows Terminal is a new multi-tabbed tool for console-based shells. It is officially available via the Microsoft Store and currently requires Windows 10 1903 or better.

    To install it from the Microsoft Store, you need to register yourself which is frustrating. If you want to install Windows Terminal anonymously (and have installed Chocolatey in the previous tip), simply run this line from an elevated PowerShell:

    # download…
    • 6 Feb 2020
  • Installing Free Chocolatey Package Management

    Chocolatey is a package management system that helps you download and install software packages. Unlike the PowerShell Gallery, Chocolatey is not limited to PowerShell modules and scripts and can install a wide variety of software including tools like Notepad++, Acrobat Reader, or the Chrome browser.

    Using Chocolatey is trivial if you are prepared to run it in an elevated shell with full Administrator privileges. While…

    • 4 Feb 2020
  • Grab Original PowerShell Language Specification

    The PowerShell team has once published the rich and detailed PowerShell 3 language reference, and since the core language never changed, this document is still extremely valuable and full of hidden treasures.

    Grab the free documentation as long as it's still available: https://www.microsoft.com/en-us/download/confirmation.aspx?id=36389



    You are a PowerShell Professional, passionate about improving your code and…

    • 31 Jan 2020
  • Downloading PowerShell Language Reference (or any file)

    Invoke-WebRequest can easily download files for you. The code below downloads the PowerShell Language Reference published by PowerShell Magazine, and opens it with the associated program:

    $url = "https://download.microsoft.com/download/4/3/1/43113f44-548b-4dea-b471-0c2c8578fbf8/powershell_langref_v4.pdf"
    
    # get desktop path
    $desktop = [Environment]::GetFolderPath('Desktop')
    $destination = "$desktop…
    • 29 Jan 2020