• Working with NTFS Streams (Part 4)

    Whenever you download a file from the Internet (or other sources deemed untrusted) and store it on a NTFS drive, Windows silently marks such files with a Zone Identifier. That’s for example why PowerShell refuses to execute scripts downloaded from outside the domain.

    You can actually look at the Zone Identifier. Just make sure you download a file from the Internet and store it on a NTFS drive. Next, use this line…

    • 15 Apr 2021
  • Working with NTFS Streams (Part 3)

    In the previous tip we explained how NTFS streams work. However, it wasn’t possible to discover the names of hidden file streams. In PowerShell 5 and better, most cmdlets accessing the filesystem received a new parameter called -Stream. With it, it is now trivial to access NTFS streams, so the example from previous scripts using the colon notation right in the path name can be rewritten now like this:

    # create a…
    • 13 Apr 2021
  • Working with NTFS Streams (Part 2)

    In the previous tip we explained how NTFS streams can store additional data about a file which raises the question how you can delete such streams, or discover hidden NTFS streams in the first place.

    To remove a hidden named stream, you use Remove-Item – just as if you wanted to delete the entire file. Here is a quick example:

    # create a sample file
    $path = "$env:temp\test.txt"
    'Test' | Out-Fi…
    • 9 Apr 2021
  • Working with NTFS Streams (Part 1)

    On NTFS file systems, you can store extra information in hidden file streams. Traditionally, PowerShell accesses file streams via colons, so this attaches hidden text information to a plain text file:

    # create a sample file
    $desktop = [Environment]::GetFolderPath('Desktop')
    $path = Join-Path -Path $desktop -ChildPath 'testfile.txt'
    'Test' | Out-File -FilePath $Path
    
    # attach hidden info to the…
    • 7 Apr 2021
  • Watching German TV Shows

    German public broadcasting companies maintain rich TV archives and let users view their shows through web interfaces. There is typically no way to download shows or easily find their download URLs.

    The following script downloads an unofficial directory listing of all the shows and their network locations:

    # download the German mediathek database as JSON file
    $path = "$env:temp\tv.json"
    $url = 'http://www…
    • 5 Apr 2021
  • Finding Last Logged-on User

    To find details about the last logged-on user on Windows, you can query the registry:

    Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\LogonUI" |
      Select-Object -Property LastLo*, Idle*
    

    The result looks similar to this:

     
    LastLoggedOnDisplayName : Tobias Weltner
    LastLoggedOnProvider    : {D6886603-9D2F-4EB2-B667-1971041FA96B}
    LastLoggedOnSAMUser     : .\tobia
    LastLoggedOnUser…
    • 1 Apr 2021
  • Using BITS to Download Files (Part 2)

    BITS (Background Intelligent Transfer System) is the technique used by Windows to download huge files such as operating system updates. You can use the service as well, for example to download files asynchronously. When you do this, you don’t need to wait for the download to complete, and you can even download super large files across multiple reboots and over the course of days. The download continues whenever the user…

    • 30 Mar 2021
  • Using BITS to Download Files (Part 1)

    BITS (Background Intelligent Transfer System) is the technique used by Windows to download huge files such as operating system updates. You can use the same system, too, to download large files. As an extra benefit, you get a nice progress bar while the file is downloading. This example downloads a NASA Mars report and plays the video after downloading it:

    $url = 'https://mars.nasa.gov/system/downloadable_items/41764_20180703_marsreport…
    • 26 Mar 2021
  • Investigating PowerShell Console Output

    When you see results from commands in the PowerShell console, typically only part of the information is displayed. To see the complete information, you need to send it to Select-Object and explicitly select all properties using the “*” wildcard:

     
    PS> Get-CimInstance -ClassName Win32_BIOS
    
    
    SMBIOSBIOSVersion : 1.7.1
    Manufacturer      : Dell Inc.
    Name              : 1.7.1
    SerialNumber      : 4ZKM0Z2
    Version…
    • 24 Mar 2021
  • Identifying Origin of Network Access

    Get-NetTCPConnection returns all current TCP network connections, but this cmdlet won’t tell you exactly who is connecting to your machine. You receive the IP address only:

     
    PS> Get-NetTCPConnection -RemotePort 443 
    
    LocalAddress  LocalPort RemoteAddress  RemotePort State       AppliedSetting OwningProcess     
    ------------  --------- -------------  ---------- -----       -------------- ---------
    192.168.2.110…
    • 22 Mar 2021
  • Exploring Folder Structures (Part 2)

    With just a couple of cmdlets, you can examine folder structures and i.e. return the sizes of subfolders in a folder tree.

    Here is an example that returns both total and relative folder sizes:

    # specify the folder that you want to discover
    # $home is the root folder of your user profile
    # you can use any folder: $path = 'c:\somefolder'
    $path = $HOME
    
    # specify the depth you want to examine (the number of levels…
    • 18 Mar 2021
  • Exploring Folder Structures (Part 1)

    Here is a quick sample illustrating how you can discover folder structures. This example takes any root folder path and recursively traverses through its subfolders.

    For each subfolder, a new custom object is returned with the file and subfolder count and the relative subfolder path:

    # specify the folder that you want to discover
    # $home is the root folder of your user profile
    # you can use any folder: $path = 'c:\somefolder…
    • 16 Mar 2021
  • Saving Text Files without BOM

    On Windows, by default many cmdlets encode text files with a BOM (Byte Order Mask) encoding. BOM writes some extra bytes at the beginning of a text file to mark the encoding used to write the file.

    Unfortunately, BOM encoding wasn’t adopted well outside the Windows world. Today, when you save a text file on a Windows system and upload it to i.e. GitHub, the BOM encoding can corrupt the file or make it entirely unreadable…

    • 12 Mar 2021
  • Trusting Self-Signed HTTPS Certificates

    If you need to access HTTPS websites that use a self-signed test certificate or a certificate that has expired or is otherwise not trustworthy, PowerShell would refuse to connect. That’s good for most cases, but occasionally you know that the destination server is safe.

    Here is some PowerShell code that trusts all HTTPS certificates by overriding the certificate policy. A new certificate policy always returns $true…

    • 10 Mar 2021
  • Converting Word Documents

    There are still floating around numerous Microsoft Office documents in old file formats (.doc instead of .docx).

    Here is a simple PowerShell function that takes an old .doc Word document, converts it and saves the converted document in .docx format. Provided the old Word document isn’t locked, this process is completely invisible and can run unattended:

    function Convert-Doc2Docx
    {
      param
      (
        [Parameter(Man…
    • 8 Mar 2021
  • Using Encoding Standards

    When working with text files, it is important to always use the same text encoding for reading and writing or else special characters can be damaged, or the text file may become unreadable.

    In PowerShell 7, all cmdlets as well as the redirection operator use the default UTF8 text encoding unless you specify a different encoding. That’s good.

    In Windows PowerShell, different cmdlets use different default encodings…

    • 4 Mar 2021
  • Fixing VSCode PowerShell Issues (Part 2)

    If VSCode won’t launch a PowerShell engine when editing a PowerShell script and instead the yellow message “Starting PowerShell” in the status bar won’t go away, then one possible fix is to use a fresh and separate portable install of PowerShell 7 as the default PowerShell engine in VSCode.

    First, run this line to create the cmdlet Install-PowerShell:

    Invoke-RestMethod -Uri https://aka.ms/inst…
    • 2 Mar 2021
  • Fixing VSCode PowerShell Issues (Part 1)

    Occasionally, VSCode stalls when trying to start the PowerShell engine, or reports errors like “Language Server Startup failed”.

    If you get the latter exception, this may be related to security settings in your enterprise. To fix, run the following line in a PowerShell console (this is one long line):

    Import-Module $HOME\.vscode\extensions\ms-vscode.powershell*\modules\PowerShellEditorServices\PowerShellEditorServices…
    • 26 Feb 2021
  • Finding PowerShell Commands

    Get-Command can help you find PowerShell commands for a given task but this cmdlet can only search for keywords in command names and parameters.

    A more sophisticated search command can be installed from the PowerShell Gallery:

    Install-Module -Name PSCommandDiscovery -Scope CurrentUser -Verbose
    

    Find-PowerShellCommand takes a keyword and returns all commands related to this keyword. It searches for your keyword in command…

    • 24 Feb 2021
  • Repairing Install-Module (PowerShellGet)

    With Install-Module, you can easily download and install additional PowerShell modules from the PowerShell Gallery (www.powershellgallery.com). However, on Windows systems this command may be broken. Many Windows systems still ship with the outdated version 1.x, and the PowerShell Gallery has switched to the internet protocol TLS 1.2 which isn’t automatically supported by older Windows versions.

    To solve problems…

    • 22 Feb 2021
  • Cross-Platform Out-GridView

    Out-GridView is one of the most frequently used cmdlets and opens a general purpose selection dialog. Unfortunately, PowerShell can display graphical elements such as windows only on the Windows operating system. On Linux and macOS, graphical cmdlets such as Out-GridView are not available.

    You may want to try the new text-based Out-ConsoleGridView instead. This cmdlet is available only for PowerShell 7 (it won’t work…

    • 18 Feb 2021
  • Discovering Package Managers on Windows (Part 2)

    In the previous tip we discussed the “Chocolatey” package manager which works best if you’d like to install software for all users (Administrator privileges required).

    Another great package manager is “Scoop” which targets regular users with no Administrator privileges. Scoop downloads and installs software strictly for the current user and as a portable app.

    Note: To be able to run scripts…

    • 16 Feb 2021
  • Discovering Package Managers on Windows (Part 1)

    In the Linux world, package managers are an established way to download and install software. On Windows, package managers are still new for many.

    If you are a Windows system administrator and would like to download and install standard software packages for all users, then “Chocolatey” would be a premier choice. This package manager works best with full Administrator privileges and installs software using their default…

    • 12 Feb 2021
  • Simplest Way to Install PowerShell 7 on Windows

    Probably the simplest and most flexible way to download and install PowerShell 7 for Windows users is to run the following one-liner:

    Invoke-RestMethod -Uri https://aka.ms/install-powershell.ps1 | New-Item -Path function: -Name Install-PowerShell | Out-Null
    

    It creates a new cmdlet Install-PowerShell with a number of useful parameters. For example, to download the latest production version of PowerShell 7 as a portable…

    • 10 Feb 2021
  • Translating Text to Morse Code

    There seem to be web services for just about anything. Here is a web service that turns text to Morse code:

    $Text = 'SOS This is an emergency!'
    
    # URL-encode text
    Add-Type -AssemblyName System.Web
    $encoded = [System.Web.HttpUtility]::UrlEncode($Text)
    
    # compose web service URL
    $Url = "https://api.funtranslations.com/translate/morse.json?text=$encoded"
    
    # call web service
    (Invoke-RestMethod -UseBasic…
    • 8 Feb 2021