Blog - Post List
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: 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
  • Power Tips: Working with GeoCoding (Part 1)

    Last year, Google changed their terms and requires an individual API key now to use their geocode API. Fortunately, there are free alternatives, so in this mini series we’d like to show you what can be done with PowerShell to handle addresses and coordinates.

    All of this requires REST API calls, so whatever information you want to send to the REST API, it needs to be encoded in a way that can be sent as part of…

    • 21 Jun 2019
  • Power Tips: Using Session Variables in Web Requests

    Sometimes, web requests that work fine in a browser do not seem to work well in PowerShell. For example, when you navigate to http://www.geocode.xyz/Bahnhofstrasse,Hannover?json=1 in a browser, you get back the coordinates of that address in JSON format.

    When you try the same within PowerShell, you get back awkward exceptions:

    $url = 'http://www.geocode.xyz/Bahnhofstrasse,Hannover?json=1'
    Invoke-RestMethod -U…
    • 20 Jun 2019
  • Power Tips: Left Side of Comparison

    When using comparison operators, always make sure the relevant part is placed left. That’s because PowerShell looks at the left side of an operator and may automatically change types of the right side. Also, comparison operators may work as filters when there is an array on the left side.

    Check out the differences:

    $array = @()
    
    '-'* 80
    $array -eq $null
    '-'* 80
    $null -eq $array
    '-'* 80
    

    • 19 Jun 2019
  • Power Tips: Subscribe to Lock and Unlock Events

    Whenever a user locks his machine, and whenever a user unlocks a machine, Windows emits an event. PowerShell can subscribe to these events and do things, for example use the text-to-speech engine to emit greetings.

    But there are a number of useful actions as well. Maybe you want to clean up when you lock your machine, close all Windows Explorer windows, start a backup, or do something else. Here is the sample code:

    f…
    • 18 Jun 2019
  • Power Tips: Finding Installed Updates (Part 2)

    The Windows Update Client maintains its own log of installed updates. Rather than querying the generic system event log, or actively searching for updates which can take some time, here is example code to query and read the installation history from your Windows Update Client:

    $Session = New-Object -ComObject Microsoft.Update.Session
      $Searcher = $Session.CreateUpdateSearcher()
      $HistoryCount = $Searcher.GetTotalHi…
    • 17 Jun 2019
  • Power Tips: Finding Installed Updates (Part 1)

    Get-Hotfix returns installed hotfixes but really only is a wrapper around the Win32_QuickFixEngineering WMI class. It is not returning all installed updates.

    A better way may be querying the event log:

    Get-EventLog  -LogName System -InstanceId 19  |
        ForEach-Object {
            [PSCustomObject]@{
                Time = $_.TimeGenerated
                Update = $_.ReplacementStrings[0]
            }
        } 
    

    Even this may not be complete…

    • 14 Jun 2019
  • Power Tips: Finding Missing Updates

    PowerShell can access the same logic that is used by the Windows Update Client, and query for missing updates:

    $UpdateSession = New-Object -ComObject Microsoft.Update.Session
    $UpdateSearcher = $UpdateSession.CreateupdateSearcher()
    $Updates = @($UpdateSearcher.Search("IsHidden=0 and IsInstalled=0").Updates)
    $Updates | Select-Object Title
    

    Here is a more sophisticated approach returning update title and KB number…

    • 13 Jun 2019
  • Power Tips: Who is Starting Hidden Programs?

    Ever wondered why your CPU load is so high at times, or why black windows open up for a split second? Then check your event log for program launches, and find out when and what was started automatically:

    Get-EventLog -LogName System -InstanceId 1073748869 |
    ForEach-Object {
    
        [PSCustomObject]@{
            Date = $_.TimeGenerated
            Name = $_.ReplacementStrings[0]
            Path = $_.ReplacementStrings[1]
            S…
    • 12 Jun 2019
  • Power Tips: Finding Logon Events

    Provided you have Administrator privileges, here is a quick and easy way of dumping all login events. This way you can find out who logged in to a particular computer, and which authentication type was used:

    #requires -RunAsAdministrator
    
    Get-EventLog -LogName Security -InstanceId 4624 |
      ForEach-Object {
          [PSCustomObject]@{
              Time = $_.TimeGenerated
              LogonType = $_.ReplacementStrings[8]
          …
    • 11 Jun 2019
  • Power Tips: Resolving URLs

    Often, URLs redirect to the final URL, so if you’d like to know where a given URL really points to, use a function like this:

    function Resolve-Url
    {
      [CmdletBinding()]
      param
      (
        [Parameter(Mandatory)]
        [string]
        $url
      )
      
      $request = [System.Net.WebRequest]::Create($url)
      $request.AllowAutoRedirect=$false
      $response = $request.GetResponse()
      $url = $response.GetResponseHeader("Location"…
    • 10 Jun 2019
  • Power Tips: Finding Size of Download

    When you download files from the internet and use PowerShell, you may want to find out how long the download will take. While you can check the size of the already downloaded binaries, to calculate a progress percentage you also know the size of the total download.

    Here is a quick way of finding out the size of a file:

    function Get-DownloadSize
    {
      [CmdletBinding()]
      param
      (
        [Parameter(Mandatory,ValueFromPipel…
    • 7 Jun 2019
  • Power Tips: Detecting Key Press

    Sometimes it would be nice if a script was able to detect a key press without interfering with the script and its inputs. This way, you could add logic where pressing SHIFT would abort a script or enable verbose logging, and in your profile script, you could load modules and perform other adjustments based on whether you hold some key while PowerShell starts.

    Which boils down to the question: what is the best and least…

    • 6 Jun 2019