• 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
  • Sharing Modules in Windows PowerShell and PowerShell Core

    Many PowerShell users start to take a look at PowerShell 7, and run it side-by-side to the built-in Windows PowerShell.

    Both PowerShell versions maintain their own locations for PowerShell modules, so when you add new modules (i.e. via Install-Module), you need to do this for both PowerShell versions separately.

    There is one folder path though that is shared by both Windows PowerShell and PowerShell 7: although introduced…

    • 27 Jan 2020
  • Installing ActiveDirectory Module

    Good news for any PowerShell users dealing with Active Directory: in recent Windows 10 builds (Enterprise, Professional), Microsoft included the RSAT tools so there is no additional download required. To use PowerShell commands for AD, simply enable the RSAT features (see below).

    Plus, finally the Active Directory PowerShell module is natively supported in PowerShell 7! If you started to use the new PowerShell side-by…

    • 23 Jan 2020
  • Testing for Pending Reboots

    When Windows installed updates or made related changes to the operating system, changes may become effective only after a reboot. While a reboot is pending, the operating system may not yet be fully protected, and you may not be able to install additional software.

    Whether a reboot is pending can be determined by testing for a special registry key:

    $rebootRequired = Test-Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion…
    • 21 Jan 2020
  • Launching PowerShell Scripts Invisibly

    There is no a built-in way to launch a PowerShell script hidden: even if you run powershell.exe and specify -WindowStyle Hidden, the PowerShell console will still be visible for a fraction of a second.

    To launch PowerShell scripts hidden, you can use a VBScript, though:

    Set objShell = CreateObject("WScript.Shell")
    path = WScript.Arguments(0)
    
    command = "powershell -noprofile -windowstyle hidden -executionpolicy…
    • 17 Jan 2020
  • Killing Non-Responding Processes

    Process objects returned by Get-Process can tell whether the process is currently responding to window messages and thus to user requests. This line takes the current PowerShell process to expose its property “Responding”:

     
    PS> Get-Process -Id $Pid | Select-Object *respond*
    
    Responding
    ----------
          True
     

    It is common for a process to occasionally become unresponsive, i.e. because of a high load and…

    • 15 Jan 2020
  • Testing Network Connections (Part 2)

    If you’d like to test whether a specific computer or URL is online, for decades ping requests (ICMP) have been used. In recent times, many servers and firewalls turn off ICMP to reduce attack surfaces. Test-NetConnection by default uses ICMP, so it fails on computers that do not respond to ICMP:

     
    PS> Test-NetConnection -ComputerName microsoft.com 
    WARNING: Ping to 40.76.4.15 failed with status: TimedOut
    WARNING…
    • 13 Jan 2020
  • Testing Network Connections (Part 1)

    PowerShell comes with Test-NetConnection which works like a sophisticated ping tool. In its default, you can ping computers:

     
    PS> Test-NetConnection -ComputerName powershell.one 
    
    
    ComputerName           : powershell.one
    RemoteAddress          : 104.18.46.88
    InterfaceAlias         : Ethernet 4
    SourceAddress          : 192.168.2.108
    PingSucceeded          : True
    PingReplyDetails (RTT) : 26 ms  
     

    Using -TraceRoute…

    • 9 Jan 2020