• SID of Current User

    Here is a one-liner that returns the SID for the current user and can be used in logon scripts, for example:


    psconf.eu – PowerShell Conference EU 2019 – June 4-7, Hannover Germany – visit www.psconf.eu There aren’t too many trainings around for experienced PowerShell scripters where you really still learn something new. But there…

    • 11 Jan 2019
  • Scanning Ports

    Here is a straightforward way to test ports on a local or remote system. You can even specify a timeout (in milliseconds):

    function Get-PortInfo
            $ComputerName = $env:COMPUTERNAME
        # try and establish a connection to port…
    • 10 Jan 2019
  • Resetting Console Colors

    It can be easy to mess up console colors in the PowerShell console. A single call with accidental values, or a script that messed with the colors, can lead to unexpected results. Check for yourself, open a PowerShell console (not an editor!), and run this:

    PS> [Console]::BackgroundColor = "Green"   

    To quickly clean up colors, run this:

    PS> [Console]::ResetColor() 

    Run Clear-Host afterwards to…

    • 9 Jan 2019
  • Solving SSL Connection Problems

    Sometimes when you try to access web services (or download internet content in general), PowerShell may bail out and complain about not being able to set up a protected SSL channel.

    Let’s take a look at such an issue. Below is a code that is calling a web service connected to the German railway system. It is supposed to list the train stations in a given city:

    $city = "Hannover"
    $url = "https://rit.bahn…
    • 8 Jan 2019
  • Deleting the Oldest Log File

    If you’re writing log activity to files, you may want to clean up things, so maybe you’d like to always delete the oldest log file when you add a new one.

    Here is a simple approach:

    # this is the folder keeping the log files
    $LogFileDir = "c:\myLogFiles"
    # find all log files...
    Get-ChildItem -Path $LogFileDir -Filter *.log |
      # sort by last change ascending
      # (oldest first)...
    • 7 Jan 2019
  • Enable Real-Time Streaming with Foreach

    Classic foreach loops are the fastest loop available but they come with a severe limitation. Foreach loops do not support streaming. You need to always wait for the entire foreach loop to finish before you can start processing the results.

    Here are some example illustrating this. With the code below, you have to wait a long time until you “see” the results:

    $result = foreach ($item in $elements)
    • 4 Jan 2019
  • Listing Network Drives

    There are many ways to create a list of network drives. One involves a COM interface that was used by VBScript as well, and we’ll pick it to illustrate a special PowerShell technique.

    To dump all network drives, simply run these lines:

    $obj = New-Object -ComObject WScript.Network

    The result may look similar to this:

    PS> $obj.EnumNetworkDrives() 
    • 3 Jan 2019
  • Sending Emails via Outlook

    You can always use Send-MailMessage to send a mail via any SMTP server. If you’d like to use your Outlook client, though, i.e. to keep access to your address books, use your companies Exchange server, or save the mail in your mail history, here is a quick function that shows how:

    function Send-OutlookMail
    • 2 Jan 2019
  • Title-Casing Strings (Capital Letter Starts Each Word)

    Polishing raw text is not always trivial, and when you’d like to make sure names or texts are well-formed, and each word starts with a capital letter, it typically involves much work.

    Funny enough, every CultureInfo object has a built-in ToTitleCase() method that does the job for you. If you convert the raw text to all lowercase before, it also takes care of all uppercase words:

    $text = "here is some TEXT that I…
    • 1 Jan 2019
  • Concatenating Text Files

    Let’s assume a script has written multiple log files in a folder, all with extension *.log. You would like to consolidate them into one big file. Here is a simple approach:

    $OutPath = "$env:temp\summary.log"
    Get-Content -Path "C:\Users\tobwe\Documents\ScriptOutput\*.log" |
      Set-Content $OutPath
    Invoke-Item -Path $OutPath

    However, this approach wouldn’t give a lot of control to you: all files…

    • 31 Dec 2018
  • Finding Windows Universal Unique Identifier (UUID)

    Every Windows installation has a unique UUID that you can use to distinguish machines. While computer names can change, the UUID won’t:

    PS> (Get-CimInstance -Class Win32_ComputerSystemProduct).UUID

    In reality, the UUID is just a GUID (Globally Unique Identifier), which comes in different formats:

    $uuid = (Get-CimInstance -Class Win32_ComputerSystemProduct).UUID
    • 28 Dec 2018
  • Formatting Date and Time (with Culture)

    In the previous tip we illustrated how Get-Date can take a format string and convert DateTime values to strings. The string conversion always uses your local language though. That might not always be what you need. Let’s check out the problem, and a solution for it:

    Here is an example outputting the weekday name for Christmas Eve in 2018:

    $christmasEve = Get-Date -Date '2018-12-24'
    Get-Date -Date $chri…
    • 27 Dec 2018
  • Formatting Date and Time

    Formatting date and time to your needs is easy with the -Format parameter provided by Get-Date. You can use it either with the current date, or external DateTime variables. Simply use the wildcards for the date and time elements you want to convert to an output string.

    Here are a couple of examples. To output the current date in ISO format, for example, run this:

    PS> Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
    • 26 Dec 2018
  • Sending PowerShell Results to PDF (Part 4)

    In the previous tip we created the function Out-PDFFile which accepts any PowerShell results and turns them into a PDF file – using the built-in printer drivers in Windows 10 and Windows Server 2016.

    We used a simple function for this to use the $Input automatic variable to easily access the piped data. If you’d rather like to use an advanced function to take advantage of mandatory parameters, we wrapped the project…

    • 25 Dec 2018
  • Sending PowerShell Results to PDF (Part 3)

    In the previous tip we explained how you can use PowerShell on Windows 10 and Windows Server 2016 to set up a PDF printer that prints anything to a PDF file, of course unattended. To make it really useful, let’s wrap it into a function called Out-PDFFile. Anything you pipe to this new command is turned into a PDF file.

    Important: for this function to work, you must have set up the printer “PrintPDFUnattended” as…

    • 24 Dec 2018
  • Sending PowerShell Results to PDF (Part 2)

    In the previous tip we illustrated how you can use the built-in “Microsoft Print to PDF” printer to send PowerShell output to PDF files. However, this printer prompts you for an output file, so it is no good for automation tasks.

    To avoid the file prompt, there is a little-known secret: simply assign the printer a port where you use the output file path as port name. Or in other words, run this script to create…

    • 21 Dec 2018
  • Sending PowerShell Results to PDF (Part 1)

    Windows 10 and Windows Server 2016 finally come with a built-in PDF printer called “Microsoft Print to PDF” that you can use from PowerShell to create PDF files. Run this to check your PDF printer:

    $printer = Get-Printer -Name "Microsoft Print to PDF" -ErrorAction SilentlyContinue
    if (!$?)
        Write-Warning "Your PDF Printer is not yet available!"
        Write-Warning "PDF printer…
    • 20 Dec 2018
  • Printing Test Pages on Printers

    Windows 10 and Windows Server 2016 come with extensive printer support thanks to the PrintManagement module. If you’d like to print official test pages on your printers, though, you need to resort to WMI.

    #requires -Version 3.0 -Modules CimCmdlets, PrintManagement
    Get-Printer | 
        Out-GridView -Title 'Print test page on selected printers' -OutputMode Multiple |
        ForEach-Object {
    • 19 Dec 2018
  • Using FileSystemWatcher Correctly (Part 2)

    In the previous tip we introduced the FileSystemWatcher and illustrated how it can miss filesystem changes when your handler code takes too long.

    To use the FileSystemWatcher correctly, you should use it asynchronously and make sure it uses a queue. So even if your script is busy processing a filesystem change, it should continue to log new filesystem changes and process them once PowerShell is done processing previous…

    • 18 Dec 2018
  • Using FileSystemWatcher Correctly (Part 1)

    A FileSystemWatcher can monitor a file or folder for changes, so your PowerShell code can immediately be notified when new files are copied to a folder, or when files are deleted or changed.

    Often, you find example code for synchronous monitoring like this:

    # make sure you adjust this
    $PathToMonitor = "c:\test"
    $FileSystemWatcher = New-Object System.IO.FileSystemWatcher
    $FileSystemWatcher.Path  = $PathToM…
    • 17 Dec 2018
  • Responding to New Event Log Entries (Part 2)

    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:

    # 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…
    • 14 Dec 2018
  • 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