• Responding to New Event Log Entries (Part 1)

    If you’d like to respond to new event log entries in real time, here is how your PowerShell code can be notified the moment a new event entry is written:

    # set the event log name you want to subscribe to
    # (use Get-EventLog -AsString for a list of available event log names)
    $Name = 'Application'
    # get an instance
    $Log = [System.Diagnostics.EventLog]$Name
    # determine what to do when an event occurs
    • 13 Dec 2018
  • Accessing Event Logs Directly

    With Get-EventLog, you can easily dump the content for any given event log, however if you’d like to directly access a given event log, you can only use the -List parameter to dump them all, then pick the one you are after:

    $SystemLog = Get-EventLog -List | Where-Object { $_.Log -eq 'System' }

    A more direct way uses casting, like this:

    $systemLogDirect = [System.Diagnostics.EventLog]'Sys…
    • 12 Dec 2018
  • Using a Stop Watch

    In PowerShell, to measure time, you can simply subtract datetime values from another:

    $Start = Get-Date
    $null = Read-Host -Prompt "Press ENTER as fast as you can!"
    $Stop = Get-Date
    $TimeSpan = $Stop - $Start

    An elegant alternative is a stop watch:

    $StopWatch = [Diagnostics.Stopwatch]::StartNew()
    $null = Read-Host -Prompt "Press ENTER as fast as you can!"
    • 11 Dec 2018
  • Using Solid Alternatives for $MyInvocation

    Lines like $MyInvocation.MyCommand.Definition can be useful to determine the folder in which the current script is stored, i.e. to access other resources located in the same folder.

    However, ever since PowerShell 3, there have been easy alternatives to find out the current script name and/or the path to the folder that contains the current script. Run the following code to test for yourself:

    • 10 Dec 2018
  • Finding Open Firewall Ports

    Here is a piece of PowerShell code that connects to the local firewall and dumps the open firewall ports:

    $firewall = New-object -ComObject HNetCfg.FwPolicy2
    $firewall.Rules |  Where-Object {$_.Action -eq 0} | 
        Select-Object Name, ApplicationName,LocalPorts

    The result may look similar to this:

    Name           ApplicationName                                         LocalPorts
    ----           ---------------      …
    • 7 Dec 2018
  • Executing Code with a Timeout (Part 2)

    In the previous tip we implemented a timeout using PowerShell background jobs so you could set a maximum time some code was allowed to run before it raised an exception.

    Here is a more lightweight alternative that uses in-process threads rather than out-of-process executables:

    function Invoke-CodeWithTimeout
    • 6 Dec 2018
  • Executing Code with a Timeout (Part 1)

    If you’d like to make sure some code won’t execute forever, you can use background jobs to implement a timeout. Here is a sample function:

    function Invoke-CodeWithTimeout
            $Timeout = 5
        $j = Start-Job -ScriptBlock $Code
        $completed = Wait-Job $j -Timeout $Timeout
        if ($completed -eq
    • 5 Dec 2018
  • Code-Signing Mini-Series (Part 5: Auditing Signatures)

    Once a PowerShell script carries a digital signature, you can easily find out who signed the script, and more importantly, whether the script is still untampered. In the previous parts of this series, you learned how to create digital certificates, and how to apply new code-signing signatures to PowerShell files. Now let’s see how you can validate scripts.

    # this is the path to the scripts you'd like to examine…
    • 4 Dec 2018
  • Code-Signing Mini-Series (Part 4: Code-Signing PowerShell Files)

    Before you give away a PowerShell script to others, it is a good idea to digitally sign it. A signature acts like a “wrapper” for your script and helps others identify who originally wrote the script and whether the script is still in original condition or was tampered with.

    To sign PowerShell scripts you need a digital code-signing certificate. In the previous tips we explained how you can create one, and…

    • 3 Dec 2018
  • Code-Signing Mini-Series (Part 3: Reading Certificates from Personal Store)

    Certificates can be installed permanently by loading them into Windows certificate store. PowerShell can access this store via its cert: drive. The following line dumps all your personal certificates:

    PS C:\> Get-ChildItem -Path Cert:\CurrentUser\my
       PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\my
    Thumbprint                                Subject                              
    • 30 Nov 2018
  • Code-Signing Mini-Series (Part 2: Reading Certificates from PFX Files)

    In the previous tip we created new code-signing test certificates both as pfx file and located in your certificate store. Today, you’ll see how you can load these (or any other certificates you got from other sources) into PowerShell.

    To load a certificate from a pfx file, use Get-PfxCertificate:

    $Path = "$home\desktop\tobias.pfx"
    $cert = Get-PfxCertificate -FilePath $Path 
    $cert | Select-Object -Pro…
    • 29 Nov 2018
  • Code-Signing Mini-Series (Part 1: Creating Certs)

    To play with digital signatures, and discover how you can sign scripts and modules, you first need a code-signing certificate. If you can’t get one from your corporate IT, PowerShell can create one for you (provided you are using Windows 10 or Server 2016).

    We wrapped the details in an easy-to-use function called New-CodeSigningCert which can create new code-signing certs in your personal certificate store, or also…

    • 28 Nov 2018
  • Converting SecureString to Clear Text

    Secure string content cannot be easily viewed:

    $password = Read-Host -Prompt 'Your password' -AsSecureString
    PS C:\> $password

    However, if you are the one who asked for the secure string in the first place, you can easily convert it back into plain text with this clever trick:

    $txt = [PSCredential]::new("X", $Password).GetNetworkCredential().Password


    • 27 Nov 2018
  • Using Catalog Files

    Catalog file support (.cat) is new in PowerShell 5.1. Cat files basically are file lists with hash values. You can use them to ensure that a given file structure is unchanged.

    Here is a simple example. It takes a folder (make sure it exists, or else rename it) and creates a cat file for the entire folder content. Note that this involves creating a hash value for each file in the folder, so keep an eye on a reasonable…

    • 26 Nov 2018
  • Making Error Records More Readable

    Whenever PowerShell encounters an error, it emits an Error Record with detailed information about the problem. Unfortunately, these objects are a bit cryptic and won’t show all of their information by default. To get to the beef, a function like the below is of invaluable help:

    function ConvertFrom-ErrorRecord
        # we receive either a legit error record...
    • 23 Nov 2018
  • Creating Write-Protected Functions

    PowerShell functions by default can be overridden anytime, and you can also remove them using Remove-Item:

    function Test-Lifespan
    Remove-Item -Path function:Test-Lifespan

    For security-relevant functions, you might want to create functions in a way that makes them immune against overwriting. Here is how:

    $FuncName = 'Test-ConstantFunc'
    $Expression = {
    • 22 Nov 2018
  • $FormatEnumerationLimit Scoping Issues

    As shown in the previous tip, the secret $FormatEnumerationLimit variable determines how many array elements are shown in output before the output is truncated. Here is an example illustrating the difference again:

    $default = $FormatEnumerationLimit
    Get-Process | Select-Object -Property Name, Threads -First 5 | Out-Default
    $FormatEnumerationLimit = 1
    Get-Process | Select-Object -Property Name, Threads -First 5 | Out…
    • 21 Nov 2018
  • Displaying Array Members in Output

    When you output objects that have arrays in their properties, only 4 array elements are displayed, then an ellipsis truncates the rest:

    PS C:\> Get-Process | Select-Object -Property Name, Threads -First 6
    Name       Threads                    
    ----       -------                    
    acrotray   {3160}                     
    AERTSr64   {1952, 1968, 1972, 8188}   
    AGSService {1980, 1988, 1992, 2000...}
    armsvc     {1920,…
    • 20 Nov 2018
  • Find All Files Two Levels Deep

    Yet another file system task: list all *.log files in a folder structure, but only to a maximum depth of 2 folder structures:

    Get-ChildItem -Path c:\windows -Filter *.log -Recurse -Depth 2 -File -Force -ErrorAction SilentlyContinue |
      Select-Object -ExpandProperty FullName

    Fortunately, PowerShell 5 added the helpful -Depth parameter to Get-ChildItem.

    Twitter This Tip! ReTweet this Tip!

    • 19 Nov 2018
  • Deleting All Subfolders Below A Given Level

    Here is another file system task that sounds worse than it actually is. Let’s say you need to remove all folders below a given level in a folder structure. Here is how:

    # Task:
    # remove all folders one level below the given path
    Get-ChildItem -Path "c:\sample\*\" -Directory -Recurse | 
        # remove -WhatIf to actually delete
        # ATTENTION: test thoroughly before doing this!
        # you may want to add…
    • 16 Nov 2018
  • Deleting All Files from a Folder Structure

    Sometimes tasks sound worse than they actually are. Let’s say you need to clear a folder structure and remove all files, leaving empty folders. Let’s further assume there are files on a whitelist that should not be deleted. With PowerShell, that’s easy to accomplish:

    # Task:
    # remove all files from a folder structure, but keep all folders,
    # and keep all files on a whitelist
    $Path = "c:\sample"…
    • 15 Nov 2018
  • Adding RSS Ticker to PowerShell Title Bar

    A new PowerShell background thread can do things for you in the background, for example updating your PowerShell window title bar with new news feeds every five seconds.

    First, let’s look at how to get to the news feed items:

    $RSSFeedUrl = 'https://www.technologyreview.com/stories.rss'
    $xml = Invoke-RestMethod -Uri $RSSFeedUrl
    $xml | ForEach-Object {
        "{0} {1}" -f $_.title, $_.description
    • 14 Nov 2018
  • Invoke-WebRequest vs. Invoke-RestMethod

    Invoke-WebRequest simply downloads the content from any web site. It is then your job to read the content and make sense of it. In the previous tip we explained how you can download PowerShell code, and execute it:

    $url = "http://bit.ly/e0Mw9w"
    $page = Invoke-WebRequest -Uri $url
    $code = $page.Content
    $sb = [ScriptBlock]::Create($code)
    & $sb

    (note: Run above code in a PowerShell console. When run from an…

    • 13 Nov 2018
  • Downloading PowerShell Code

    In the previous tip we explained how Invoke-WebRequest can be used to download the raw HTML content for any web page. This can also be used to transport PowerShell code. Invoke-WebRequest downloads anything a web server serves, so the below example downloads a PowerShell script:

    $url = "http://bit.ly/e0Mw9w"
    $page = Invoke-WebRequest -Uri $url
    $code = $page.Content
    $code | Out-GridView

    Once you are confident…

    • 12 Nov 2018
  • Hiding Progress Bars

    Sometimes, cmdlets automatically display a progress bar. Here is an example of such a progress bar:

    $url = "http://www.powertheshell.com/reference/wmireference/root/cimv2/"
    $page = Invoke-WebRequest -URI $url

    Invoke-WebRequest retrieves the raw content for a web page, and if retrieving the content takes a while, a progress bar is shown.

    Whenever you run a cmdlet that shows a progress bar, you can hide the progress…

    • 9 Nov 2018