• Auto-Creating a List of HTTP Response Codes

    In the previous example we looked at how numeric HTTP response codes can automatically be converted to descriptive text, simply by converting them to the type System.Net.HttpStatusCode.

     
    PS> [System.Net.HttpStatusCode]500
    InternalServerError
     

    This works because System.Net.HttpStatusCode is a so-called “enumeration” and acts like a “lookup table”. You can easily dump all members of an enumeration, and for example…

    • 22 Aug 2019
  • Converting HTTP Response Codes

    In the previous example we created a small PowerShell function that checks web site availability, and as part of the test results, a HTTP response code was returned. Let’s check out how this numeric code can be easily converted into a meaningful text message.

    Here is the function again that tests web sites:

    function Test-Url
    {
      param
      (
        [Parameter(Mandatory,ValueFromPipeline)]
        [string]
        $Url
      )
      …
    • 20 Aug 2019
  • Test Web Site Availability

    When a web site is unavailable, often the question is whether it’s you, or whether the web site is generally down for everyone else, too. PowerShell can ask a web service to check web site availability for you. Here is a simple wrapper function:

    function Test-Url
    {
      param
      (
        [Parameter(Mandatory,ValueFromPipeline)]
        [string]
        $Url
      )
      
      Add-Type -AssemblyName System.Web
      
      $check = "https://isitdown…
    • 16 Aug 2019
  • Unit Conversion via Web Service

    Accessing RESTful web services is trivial for PowerShell: simply send your input data to a public web service, and receive the results.

    Here are three PowerShell functions designed to each do a numeric conversion:

    function Convert-InchToCentimeter
    {
      param
      (
        [Parameter(Mandatory)]
        [Double]
        $Inch
      )
      [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
      $url = 'https://ucum…
    • 14 Aug 2019
  • Validating Active Directory Credentials

    PowerShell can validate AD username and passwords against the Active Directory:

    Add-Type -AssemblyName System.DirectoryServices.AccountManagement
    $account = New-Object System.DirectoryServices.AccountManagement.PrincipalContext([DirectoryServices.AccountManagement.ContextType]::Domain, $env:userdomain)
    
    $account.ValidateCredentials('user12', 'topSecret')
    

    Note that this approach is for diagnostic purposes…

    • 12 Aug 2019
  • Numbering Output (Part 1)

    If you’d like to add an incrementing number to your output, here is a simple way:

    Get-Process |
      Select-Object -Property '#', ProcessName, CPU -First 10 |
      ForEach-Object -begin { $i = 0} -process {
        $i++
        $_.'#' = $i
        $_
      } -end {}
    

    Select-Object adds a new property called “#”, and ForEach-Object adds an auto-incrementing number to it. The result looks similar to this:

     
    • 8 Aug 2019
  • Accepting Masked Passwords

    If you ever write PowerShell functions that need to accept sensitive input such as passwords, make sure you allow users to submit SecureString input. If you accept passwords via clear text, there is a substantial risk that others may see the password while being entered, or (even worse) that the password is logged and later can be found in dump files.

    Here is a simple framework that illustrates how you can achieve safe…

    • 6 Aug 2019
  • Finding Hidden PowerShell Applications

    The most widely known PowerShell hosts are certainly powershell.exe and powershell_ise.exe because they ship out-of-the-box. However, there can be many more (and hidden) PowerShell hosts running. Any software that instantiates the PowerShell engine is a PowerShell host. This could be Visual Studio Code (with the PowerShell extension installed), Visual Studio, or any other similar software.

    To find out all currently running…

    • 2 Aug 2019
  • Controlling Processor Affinity

    Most modern computers have more than one processor, either physical or logical. If you’d like to find out the number of processors, here is a chunk of PowerShell code:

    Get-WmiObject -Class Win32_Processor | 
      Select-Object -Property Caption, NumberOfLogicalProcessors
    

    The result may look similar to this:

     
    Caption                              NumberOfLogicalProcessors
    -------                              -----…
    • 31 Jul 2019
  • Dumping All Passwords from Chrome

    In the previous tip we illustrated how you can dump all passwords from your personal Windows Password Vault. The same is true for basically any password manager as these programs are designed to return the passwords they store for you.

    Google Chrome browsers store your personal passwords (and website history) in a SQLLite database. PowerShell can easily access this database and dump the information for you. To be able…

    • 29 Jul 2019
  • Dumping Personal Passwords from Windows

    Windows has a protected password vault where it can store your secret passwords so you don’t have to always enter them manually in Internet Explorer or Edge.

    If you get used to automated password managers, you may occasionally forget the original passwords. Here is a super simple PowerShell way to dump all of your passwords stored in the Windows password vault:

    # important: this is required to load the assembly…
    • 25 Jul 2019
  • Installing Google Chrome via PowerShell

    To download and install the Google Chrome browser, simply combine a couple of generic PowerShell commands:

    $Installer = "$env:temp\chrome_installer.exe"
    $url = 'http://dl.google.com/chrome/install/375.126/chrome_installer.exe'
    Invoke-WebRequest -Uri $url -OutFile $Installer -UseBasicParsing
    Start-Process -FilePath $Installer -Args '/silent /install' -Wait
    Remove-Item -Path $Installer
    

    Twitter This Tip! ReTweet…

    • 23 Jul 2019
  • Using Pop-up Dialogs that Are Always Visible

    In the previous tip we used an old COM technique to display a pop-up box with a built-in timeout. That worked pretty well except that the dialog box can be covered under your PowerShell window at times.

    With a little-known trick, you can make sure the dialog box will always open on top of all other windows:

    $shell = New-Object -ComObject WScript.Shell
    $value = $shell.Popup("You can't cover me!", 5, '…
    • 19 Jul 2019
  • Use Hash Tables to Make Code Readable

    Maybe you stumbled across code like this in the past:

    $shell = New-Object -ComObject WScript.Shell
    $value = $shell.Popup('Restart Computer?', 5, 'Important', 36)
    
    "Choice: $value"
    

    This chunk of code opens a dialog box and asks the user whether it is OK to restart the computer. The pop-up dialog has a built-in timeout so the code will never stall, even if running unattended.

    However, since PowerShell…

    • 17 Jul 2019
  • Increasing Pipeline Speed

    The PowerShell pipeline tends to be slow when it is processing a lot of elements. This can take a lot of time:

    $result = 1..15000 | 
        ForEach-Object {
            "Line $_"
        } 
    

    A much faster approach replaces ForeEach-Object with an anonymous script block and is up to 200x faster:

    $result = 1..15000 | 
        & { process {
            "Line $_"
        }}
    

    Twitter This Tip! ReTweet this Tip!

    • 15 Jul 2019
  • Detecting Key Presses

    It may be useful for PowerShell to know whether a given key is currently pressed. This way, your profile script could, for example, do things during PowerShell startup based on keys you hold. For example, when you hold the left CTRL key while launching PowerShell, your profile script could preload certain modules or connect you to servers.

    Here is how PowerShell detects pressed keys:

    # this could be part of your profile…
    • 11 Jul 2019
  • Overriding Out-Default (Part 3)

    Advanced PowerShell users often find themselves doing one of three things:

    • They run a previous command and add Get-Member to learn more about the objects emitted
    • They run a previous command and add Select-Object * to see all properties
    • They run a previous command and pipe it to Out-GridView to keep the results in reach

    All three can now be accomplished much more easily, and works in any PowerShell, including the console…

    • 9 Jul 2019
  • Overriding Out-Default (Part 2)

    When you override Out-Default to do something meaningful, you really want to make sure the old behavior isn’t lost, and instead just something new is added. Here is an example that uses the concept of “Proxy Functions”.

    The original input is forwarded (proxied) to the original Out-Default cmdlet. In addition, the function opens its own private Out-GridView window and echoes the output to this window…

    • 5 Jul 2019
  • Overriding Out-Default (Part 1)

    Out-Default is a hidden PowerShell cmdlet that gets called at the end of each command, and outputs results to the console. You can override this function with your own. If you overwrite it with an empty function, for example, all output is discarded – or results in a “SECRET!” message:

    function Out-Default
    {
        'SECRET!'
    }
    

    This is how you remove custom overrides:

     
    PS C:\> del function:Out…
    • 3 Jul 2019
  • Use Out-GridView as Output Window

    Typically, Out-GridView opens a window and displays whatever you pipe into the cmdlet:

     
    PS C:\> Get-Service | Out-GridView 
     

    However, with a little trick Out-GridView becomes even more versatile. You can pipe information to the same output window whenever you want to.

    First, get yourself an instance of Out-GridView that thinks it is running in a pipeline:

    $pipeline = { Out-GridView }.GetSteppablePipeline()
    $pipe…
    • 1 Jul 2019
  • Beer Challenge Results: Shortest Code for Password Analysis

    At psconf.eu there was recently a challenge for the shortest code to check for how often a password was previously pwnd (hacked). Here is the result (credits to Daniel Rothgänger):

    [Net.ServicePointManager]::SecurityProtocol='Tls12'
    'P@ssw0rd'|sc p -N;$a,$b=(FileHash p -A SHA1|% h*)-split'(?<=^.{5})';((irm api.pwnedpasswords.com/range/$a)-split"$b`:(\d+)")[1]  
    

    You can either…

    • 28 Jun 2019
  • Geocoding: Sentiment Analysis (Part 5)

    Some geocoding APIs provide sophisticated sentiment analysis like in the example below:

    "Most important museums of Amsterdam are located on the Museumplein, located at the southwestern side of the Rijksmuseum." |
      ForEach-Object -Begin {$url='https://geocode.xyz'
        $null = Invoke-RestMethod $url -S session
      } -Process {
        Invoke-RestMethod $url -W $session -Method Post -Body @{scantext=$_;geoi…
    • 27 Jun 2019
  • Geocoding: Text Scanning (Part 4)

    Geocoding can automatically extract geolocations from text. This example also shows a new way of submitting information to a server: in the example below, data is posted to the server using the same mechanism that is used in HTML forms. This is typically done to avoid having to URL-encode large amounts of data because when POST is used, the data travels in the header of the request, not the URL. This also allows more…

    • 26 Jun 2019
  • Geocoding: Converting Lat/Long to Addresses (Part 3)

    Today, we’d like to do the opposite and translate latitude and longitude into an address:

    '52.37799,9.75195' |
      ForEach-Object -Begin {$url='https://geocode.xyz'
        $null = Invoke-RestMethod $url -S session
      } -Process {
        $coord = $_
        Invoke-RestMethod "$url/${address}?geoit=json" -W $session
      }
    

    Twitter This Tip! ReTweet this Tip!

    • 25 Jun 2019
  • Geocoding: Converting Addresses to Lat/Long (Part 2)

    Let’s start with translating addresses into latitude and longitude coordinates. We assume you read the previous parts to fully understand the code sample.

    Here is some sample code that takes any number of addresses, and returns their latitude and longitude for you:

    'One Microsoft Way, Redmond',
    'Bahnhofstrasse 12, Hannover, Germany' |
      ForEach-Object -Begin {$url = 'https://geocode.xyz'
    • 24 Jun 2019