• Converting UNIX Time to DateTime

    “Unix time” counts the seconds that have passed since 01/01/1970.

    For example, in Windows, you can read the installation date from the Windows Registry, and the returned value is “Unix time”:

    $values = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' 
    $installDateUnix = $values.InstallDate
    
    $installDateUnix
    

    The result is a large number similar to this:

     
    1601308412…
  • Creating Dynamic Parameters

    Dynamic parameters are a special breed of parameters that can be shown or hidden based on runtime conditions. Your PowerShell functions could for example have just one parameter called -Action, and based on the action the user chooses, additional parameters would show. Or, you could have parameters show only when the user has Administrator privileges.

    Unfortunately, composing dynamic parameters isn’t trivial. With the…

  • Turning Text into Individual Lines (Part 3)

    In the previous tip we split a chunk of multi-line text into individual lines and removed any empty lines.

    However, when a line isn’t really empty but contains whitespace (spaces or tabulators), it is still returned:

    # $data is a single string and contains blank lines
    $data = @'
    
    Server1
    
       
    Server2
    Cluster4
    
    
    '@
    
    $data = $data.Trim()
    
    # split in single lines and remove empty lines
    $regex = '[\r\n]…
  • Turning Text into Individual Lines (Part 2)

    Let’s assume your script gets text input data, and you need to split the text into individual lines. In the previous tip we suggested a number of regular expressions to do the job. But what if the input text contains blank lines?

    # $data is a single string and contains blank lines
    $data = @'
    
    Server1
    
    
    Server2
    Cluster4
    
    
    '@
    
    # split in single lines and remove empty lines
    $regex = '[\r\n]{1,}'
    

    As…

  • Turning Text into Individual Lines (Part 1)

    Occasionally, you need to process multi-line text line by line. Here is an example of a multi-line string to start with:

    # working with 1-dimensional input
    
    # $data is a single string
    $data = @'
    Server1
    Server2
    Cluster4
    '@
    
    $data.GetType().FullName
    $data.Count
    

    An efficient way to split the text into individual lines is using the -split operator with a regular expression that can deal with the variety of platform…

  • Taking Screenshot

    With types found in System.Windows.Forms, PowerShell can easily capture your screen and save the screenshot to a file. The code below captures your entire virtual screen, saves the screenshot to file, then opens the bitmap file in the associated program (if any):

    $Path = "$Env:temp\screenshot.bmp"
    Add-Type -AssemblyName System.Windows.Forms
    
    $screen = [System.Windows.Forms.SystemInformation]::VirtualScreen
    
  • Disabling Local “Guest” Account

    Windows comes with the built-in account called “Guest”. Since this account is seldomly used, you may want to disable it. Else, its well-known name could serve as a vector for attackers.

    Since the account name is localized and can slightly vary from culture to culture, to identify the account use its SID:

     
    PS> Get-Localuser | Where-Object Sid -like 'S-1-5-*-501'
    
    Name  Enabled Description 
    ----  ------- -…
  • Renaming Local Administrator Account

    For security reasons, you may want to consider renaming the built-in local Administrator account. This account is very powerful, and its name is easily guessable so it is a common vector for attackers. Before you rename this account, make sure you understand the consequences:

    • The account continues to work but you now need to use the newly assigned name to log on with this account. Make sure there are no automatic logon…
  • Identifying Local Administrators Group

    Any member of the built-in Administrators group has access to extensive privileges, so checking the members of this group can be part of a security audit. While the “Administrators” group exists by default, its name can vary from culture to culture because it is localized. On German systems, for example, the group is called “Administratoren”.

    To access the group regardless of culture and naming…

  • Identifying Local Administrator Account

    There are a few default accounts on Windows machines such as the local “Administrator” account. While this account exists by default, its name can vary from culture to culture, and its name can also be renamed.

    To always identify the local Administrator account regardless of its name, search local accounts by SID (security identifier). The local Administrator account SID always starts with ‘S-1-5-‘ and uses…

  • Identifying Connected Domain

    One quick way to determine the name of the domain you are connected to is WMI:

     
    PS> Get-CimInstance -ClassName Win32_NTDomain
    
    DomainName       DnsForestName                                  DomainControllerName
    ----------       -------------                                  --------------------
     

    If you are not connected to a domain, the result is an empty object.



    Twitter This Tip! ReTweet this Tip!

  • Simple Built-In Password Generator

    There is a hidden gem in the .NET System.Web assembly which lets you create random passwords of any length in no time:

    # total password length
    $Length = 10
    
    # number of non-alpha-chars
    $NonChar = 3
    
    Add-Type -AssemblyName 'System.Web'
    $password = [System.Web.Security.Membership]::GeneratePassword($Length,$NonChar)
    
    "Your password: $password"
    



    Twitter This Tip! ReTweet this Tip!

  • Creating Dummy Test Files

    If you need to test file system load, test failover clusters, or need large dummy files otherwise, rather than creating new files and slowly filling them with random data, try this:

    $filepath = "$env:temp\testfile.txt"
    $sizeBytes = 5.75MB
    
    $file = [System.IO.File]::Create($filepath)
    $file.SetLength($sizeBytes)
    $file.Close()
    $file.Dispose()
    
    # show dummy file in Windows Explorer
    explorer /select,$filepath
    

    This…

  • Reading HTTP Headers from Websites

    When you navigate to a web page, your browser silently receives meta information inside the HTTP header which is typically invisible.

    To display the HTTP header information for any website, try this:

    # replace URL with any web page you like:
    $url = 'www.tagesschau.de'
    (Invoke-WebRequest -Method Head -Uri $url -UseBasicParsing).RawContent
    

    The trick is to use the -Method parameter and submit the “Head” value to…

  • Using FTP: Uploading File (Part 4)

    PowerShell does not come with cmdlets to download and upload data via FTP. However, you can use .NET for this.

    To upload a file from your local drive to an FTP server, try the code below:

    $localFile = "C:\test.txt"
    
    $username='testuser'
    $password='[email protected]'
    
    [System.Uri]$uri = "ftp://${username}:[email protected]/test.txt"
    $webclient = [System.Net.WebClient]::new()
    $webclient
  • Using FTP: Downloading Binary File (Part 3)

    PowerShell does not come with cmdlets to download and upload data via FTP. However, you can use .NET for this.

    To download a file from an FTP server in binary mode, try the code below which also illustrates how you can authenticate with explicit credentials:

    $username='testuser'
    $password='[email protected]'
    [System.Uri]$uri='ftp://192.168.1.123/test.txt'
    
    $localFile = 'C:\test.txt'
    
    $ftpreques…
  • Using FTP: Downloading File (Part 2)

    PowerShell does not come with cmdlets to download and upload data via FTP. However, you can use .NET for this.

    To download a file from an FTP server, try using this code:

    $localFile = "C:\test.txt"
    
    $username='testuser'
    $password='[email protected]'
    
    [System.Uri]$uri = "ftp://${username}:[email protected]/test.txt"
    $webclient = [System.Net.WebClient]::new()
    $webclient.DownloadFile($ur…
  • Using FTP: Listing Folders (Part 1)

    PowerShell does not come with cmdlets to download and upload data via FTP. However, you can use .NET for this.

    To display the contents of an FTP folder, try using this code:

    $username='testuser'
    $password='[email protected]'
    $ftp='ftp://192.168.1.123'
    $subfolder='/'
    
    [System.Uri]$uri = $ftp + $subfolder
    $ftprequest=[System.Net.FtpWebRequest]::Create($uri)
    $ftprequest.Credentials= [System.Net.Ne…
  • Discovering Public IP Address

    Using a web service, it is almost trivial to determine your public IP address and information about your ISP:

     
    PS> Invoke-RestMethod -Uri https://ipinfo.io
    
    
    ip       : 84.165.49.158
    hostname : p54a5319e.dip0.t-ipconnect.de
    city     : Hannover
    region   : Lower Saxony
    country  : DE
    loc      : 52.3705,9.7332
    org      : AS3320 Deutsche Telekom AG
    postal   : 30159
    timezone : Europe/Berlin
    readme   : https://ipinfo.io/missingauth…
  • Displaying Warning Dialog (Part 2)

    In the previous tip we created new shortcut files, and you have seen how the CreateShortcut() method provides methods to control almost any detail of a shortcut. Here’s the code again that creates a PowerShell shortcut on your Desktop:

    Now here is a trick that may help you always display the dialog on top of other windows. For this, the code below creates a new dummy window and makes sure this window is positioned…

  • Displaying Warning Dialog (Part 1)

    Here is a quick code sample that displays a popup warning dialog:

    Add-Type -AssemblyName  System.Windows.Forms
    $message = 'Your system will shutdown soon!'
    $title = 'Alert'
    
    [System.Windows.Forms.MessageBox]::Show($message, $title, [System.Windows.Forms.MessageBoxButtons]::OKCancel, [System.Windows.Forms.MessageBoxIcon]::Warning)
    

    These are the available button styles:

     
    PS> [Enum]::GetNames([System.Windows…
  • Error Handling for Console Commands

    Occasionally it is useful and even necessary to use console applications in PowerShell scripts. In the previous tip, for example, we looked at ways to remove mapped network drives, and even though Remove-PSDrive claims to be able to do this, the most reliable way is to still use the old net.exe console command.

    Let’s take a quick look at how you can check whether or not a console command completed successfully.

  • Removing Network Drives

    While Remove-PSDrive can remove all kinds of drives including network drives, changes may not take effect until the system reboots. That’s of course ridiculous.

    This task is a good example why it is useful that PowerShell made console applications equal citizen. In fact, even in year 2021 the most reliable way to remove a network drive is to use the old but proven net.exe. The example below removes network drive…

  • Listing Network Drives

    There are many ways to list mapped network drives. One of them uses PowerShell’s Get-PSDrive and checks to see whether the target root starts with “\\”, indicating a UNC network path:

     
    PS> Get-PSDrive -PSProvider FileSystem | Where-Object DisplayRoot -like '\\*'
    
    Name           Used (GB)     Free (GB) Provider      Root                    CurrentLocation
    ----           ---------     --------- -----…
  • Reading Printer Properties (Part 3)

    In previous tips we looked at how you can use Get-PrinterProperty to read printer properties for locally installed printers. This cmdlet is part of the PrintManagement module which ships with all Windows operating systems.

    Important: Since property names are print driver specific, this cmdlet can be awesome if you need to manage the same types of printers throughout your enterprise. It is not a first choice if you want…