• Playing Sounds

    If all you need is a beep, then PowerShell can help you easily:

    $frequency = 800
    $durationMS = 2000
    [console]::Beep($frequency, $durationMS)
    

    If you’d like something more sophisticated, then you can also have PowerShell play a system sound:

    [System.Media.SystemSounds]::Asterisk.Play()
    

    Here is a list of supported system sounds:

     
    PS> [System.Media.SystemSounds] | Get-Member -Static -MemberType Property
    
    
       TypeName…
    • 15 Mar 2018
  • Sort IPv4 and IPv6 Addresses Correctly

    When you try and sort IPv4 addresses via Sort-Object, this fails:

     
    PS> '10.1.2.3', '2.3.4.5', '1.2.3.4' | Sort-Object
    1.2.3.4
    10.1.2.3
    2.3.4.5 
     

    This is no surprise because the data is of type “string”, so Sort-Object uses alphanumeric sorting. In the previous tip we showed how you can cast the data to [Version] and pretend you are sorting software versions:

     
    PS> '10.1.2.3', …
    • 14 Mar 2018
  • Sort IPv4 Addresses Correctly

    In the previous tip we published a super-fast function called Test-OnlineFast, and this function was able to ping an entire IP segment in record time:

     
    PS> $iprange = 1..200 | ForEach-Object { "192.168.189.$_" }
    
    PS> Test-OnlineFast -ComputerName $iprange
    
    Address         Online DNSName                            Status           
    -------         ------ -------                            ------           
    192.168.189…
    • 13 Mar 2018
  • Final Super-Fast Ping Command

    In the previous tip series, we developed a new function called Test-OnlineFast that can ping multiple computers in record time. For some reason, the final version of this function did not include the pipeline support we promised. Here is the complete function again for you:

    function Test-OnlineFast
    {
        param
        (
            # make parameter pipeline-aware
            [Parameter(Mandatory,ValueFromPipeline)]
            [stri…
    • 12 Mar 2018
  • Backing Up Event Logs

    There are a number of useful cmdlets to manage event logs, however one functionality is missing:

     
    PS> Get-Command -Noun EventLog 
    
    CommandType Name            Version Source                         
    ----------- ----            ------- ------                         
    Cmdlet      Clear-EventLog  3.1.0.0 Microsoft.PowerShell.Management
    Cmdlet      Get-EventLog    3.1.0.0 Microsoft.PowerShell.Management
    Cmdlet      Limit…
    • 9 Mar 2018
  • Converting a Windows Error ID into Friendly Text

    When you call low level functions from PowerShell, often you get back a numeric return value. If the return value came from a Windows API function, here is a super easy way to translate it into a meaningful text:

    For example, whenever an API function fails due to missing access, it returns the value 5. Let’s translate it to a meaningful text:

     
    PS> New-Object -TypeName ComponentModel.Win32Exception(5)
    Access is…
    • 8 Mar 2018
  • Finding Registered Event Log Source Names

    When you write events to an event log using Write-EventLog, you must specify a valid source name. However, there is no easy way of finding out which source files are registered for a particular event log. This can also bite you when you create a new event log using New-EventLog: you must not specify any source names that are already in use by another event log.

    Here is a simple approach to find out all source names, and…

    • 7 Mar 2018
  • Easy Logging by Using Event Logs

    Often scripts need to log what they do, and PowerShell scripters invest a lot of thought and time on logging information to text files.

    As an alternative, you can easily reuse the work invested by Microsoft: PowerShell can use the event log system to log information. To test-drive, create a new event log using the code below. This part requires Administrator privileges (writing to the log does not):

    #requires -RunAsAdministrator…
    • 6 Mar 2018
  • Uncover Tiny URLs

    Tiny URLs like “http://bit.ly/e0Mw9w” are short and convenient to use, however they often mask the true origin as well.

    PowerShell can uncover tiny URLs by finding their true target:

    $url = "http://bit.ly/e0Mw9w"
    
    $request = [System.Net.WebRequest]::Create($url)
    $request.AllowAutoRedirect=$false
    $response=$request.GetResponse()
    $trueUrl = $response.GetResponseHeader("Location")
    "$url -…
    • 5 Mar 2018
  • Automatic Wallpaper Downloader

    Are you tired of boring wallpapers for your desktop? PowerShell can get you new wallpapers! Here’s the function:

    function Download-Wallpaper
    {
        param
        (
            [string]
            [Parameter(Mandatory)]
            $Folder,
     
            [Parameter(ValueFromPipeline)]
            [Int]
            $Page=1
        )
        
        begin
        {
            $url = "http://wallpaperswide.com/page/$Page"
            $targetExists = Test…
    • 2 Mar 2018
  • Saving Values to Excel Sheet

    Occasionally, you may have to update values in an Excel spreadsheet. PowerShell can access the Excel object model however this is quite slow. Here is an example that opens an Excel file, then writes information to A1 cell, and finally saves the changes.

    Make sure you adjust the path to point to an existing Excel file.

    $excel = New-Object -ComObject Excel.Application
    # open Excel file
    $workbook = $excel.Workbooks.Open
    • 1 Mar 2018
  • Reading Excel Cells

    Occasionally, you may have to read information from Excel spreadsheets. PowerShell can access the Microsoft Excel object model albeit it is quite slow.

    Here is example code that illustrates how you access Excel cells. Make sure you adjust the path in the code below so it points to a valid Excel file. The code then reads the content of A1 cell:

    $excel = New-Object -ComObject Excel.Application
    # open Excel file
    $workbo…
    • 28 Feb 2018
  • Permanently Setting Environment Variables

    PowerShell can set environment variables only in its process set, so these changes will not persist and are not visible outside of PowerShell.

    To permanently set environment variables, here is a simple function:

    function Set-EnvironmentVariable
    {
        param
        (
            [string]
            [Parameter(Mandatory)]
            $Name,
     
            [string]
            [AllowEmptyString()]
            [Parameter(Mandatory)]
            $Value,
    • 27 Feb 2018
  • Select-Object and -ExcludeProperty

    Here is a line of code that often puzzles PowerShell users:

    Get-Service | Select-Object -ExcludeProperty Name
    

    When you use Select-Object, its -ExcludeProperty parameter does not seem to do anything. The truth is: -ExcludeProperty only works when you also use -Property. So this works:

    Get-Service | Select-Object -ExcludeProperty Name -Property Status, DisplayName, Name
    

    However, this is ridiculous: why would you specify…

    • 26 Feb 2018
  • Forcefully Close All PowerShell ISE Documents

    Here’s a code snippet that forcefully closes all open documents in the PowerShell ISE. Be aware: it closes all documents without asking to save. This can be useful if you goofed around and have no intention to save your scripts:

    foreach ($tab in $psise.PowerShellTabs)
    {
        $files = $tab.Files
        foreach ($file in $files)
        {
            $files.Remove($file, $true)
        }
    }
    

    When you run this, you will receive an…

    • 23 Feb 2018
  • Creating Highspeed Ping (Part 6)

    In the final part of our mini-series, we add pipeline awareness to our super-fast Test-OnlineFast function. You now can pipe computer names into the function like this:

     
    PS> 1..200 | ForEach-Object { "192.168.189.$_" } | Test-OnlineFast
    
    Address         Online DNSName                            Status           
    -------         ------ -------                            ------           
    192.168.189.200   True DESKTOP…
    • 22 Feb 2018
  • Creating Highspeed Ping (Part 5)

    In the previous tip we created a lightning fast new PowerShell function called Test-OnlineFast which used WMI to ping any number of computers with high performance. Today we’ll make it even more useful by adding a number of additional properties to the ping result.

    Let’s first check how Test-OnlineFast works. Here are some examples. Let’s first ping a number of computers. You can use both computer names and IP addresses…

    • 21 Feb 2018
  • Creating Highspeed Ping (Part 4)

    In the previous tip we illustrated how WMI can ping multiple computers in a very fast way. So today, let’s wrap the code into a reusable PowerShell function. It can ping one or many computers with lightning speed.

    Here’s the function code:

    function Test-OnlineFast
    {
        param
        (
            [Parameter(Mandatory)]
            [string[]]
            $ComputerName,
     
            $TimeoutMillisec = 1000
        )
        
        # convert…
    • 20 Feb 2018
  • Creating Highspeed Ping (Part 3)

    In the previous tip we illustrated how WMI can ping multiple computers in a very fast way. However, the syntax was awkward. So let’s rewrite the code to make it easier to specify the list of computers you want to ping:

    # ping the specified servers with a given timeout (milliseconds)
    $ComputerName = 'google.de','microsoft.com','r13-c00'
    $TimeoutMillisec = 1000
     
    # convert list of computers…
    • 19 Feb 2018
  • Creating Highspeed Ping (Part 2)

    In the previous tip we illustrated how WMI can ping computers with a predefined timeout. WMI can do more: it can ping multiple computers lightning fast even though the syntax is a bit awkward.

    Here is how you can ping more than one computer:

    # ping the specified servers with a given timeout (milliseconds)
    $TimeoutMillisec = 1000
    
    Get-WmiObject -Class Win32_PingStatus -Filter "(Address='microsoft.com' or Address='r13-c14…
    • 16 Feb 2018
  • Creating High-Speed Ping (Part 1)

    Pinging computers is a frequently needed task. The PowerShell cmdlets such as Test-Connection can do pings but do not have a timeout limit, so when you try and ping offline systems, it may take a long time to get a result.

    WMI can ping with timeouts. Here is how:

    $ComputerName = 'microsoft.com'
    $TimeoutMillisec = 1000
    
    Get-WmiObject -Class Win32_PingStatus -Filter "Address='$ComputerName' and timeout=$TimeoutMillisec…
    • 15 Feb 2018
  • Getting Help for PowerShell

    Provided you have downloaded the PowerShell help files, there is an easy way to get help for all kinds of PowerShell topics.

    First, make sure you downloaded the help: launch PowerShell with Administrator privileges, and run this:

    Update-Help -UICulture en-us -Force
    

    Next, check out the “about”-topics you got:

    Get-Help about_*
    

    In the PowerShell ISE, all you’d need to do is click one of the about topics listed…

    • 14 Feb 2018
  • Exploiting Select-Object

    Select-Object is a basic cmdlet that most PowerShell users use frequently. However, it has some tricks that are not well known.

    In its most basic form, Select-Object selects the properties that are visible. If you don’t use Select-Object, then PowerShell determines which properties are shown, and how they are formatted:

    Get-ChildItem -Path c:\windows\system32 -Filter *.dll
    

    If you add Select-Object, you can determine…

    • 13 Feb 2018
  • Reading RunOnce Key

    The RunOnce key in the Windows Registry stores all auto-starting executables. It may be empty. To check for auto-starting applications, try this:

    $path = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce'
    $properties = Get-ItemProperty -Path $path 
    $properties
    

    Again, this key may have no values. If it has, each auto-starting program has its own value with its own name. To read just the paths for auto-starting…

    • 12 Feb 2018
  • Creating Random Passwords

    Here is another small script to produce random passwords consisting of a defined number of capitals, letters, numbers, and special characters:

    $length = 10
    $length_small = $length - 3
    $numbers = '2,3,4,5,6,7,8,9' -split ','
    $large = 'A,B,C,D,E,F,G,H,K,L,M,N,P,R,S,T,U,V,W,X,Y,Z' -split ','
    $small = 'A,B,C,D,E,F,G,H,K,L,M,N,P,R,S,T,U,V,W,X,Y,Z'.ToLower() -split ','
    $speci…
    • 9 Feb 2018