• Remove User Profiles Via Dialog

    We’ve received massive feedback on our tips dealing with user profile management, so we decided to add a couple of additional tips.

    In the previous tip we illustrated how WMI can delete user profiles. Some users recommended to use Remove-WmiObject instead of the internal WMI method Delete(). However, it turned out that Remove-WmiObject cannot delete user profile instances.

    The code below sums up all the details…

    • 15 Jan 2018
  • Find User Profiles

    We’ve received massive feedback on our tips dealing with user profile management, so we decided to add a couple of additional tips.

    Typically, every time a user logs on to a system, locally or remote, a user profile is created. So over time, there can exist a lot of orphaned user profiles. If you’d like to manage user profiles (including deleting unwanted ones), make sure you ignore special user profiles that are…

    • 12 Jan 2018
  • List User Profiles

    We've received a massive feedback on our tips dealing with user profile management, so we decided to add a couple of additional tips.

    WMI can easily enumerate all user profiles on a system but lists only the SID (security identifier), not the plain text user name.

    Get-CimInstance -ClassName Win32_UserProfile |

    To improve this, here is a simple chunk of code that converts SIDs to user names:

    $sid =
    • 11 Jan 2018
  • Understanding and Avoiding Double-Hop

    When a script is executed remotely, you can run into “Access Denied” issues that often are related to the double-hop issue. Here is an example, and then we illustrate how to work around it:

    $target = 'serverA'
    $code = {
        # access data from another server with transparent authentication
        Get-WmiObject -Class Win32_BIOS -ComputerName serverB
    Invoke-Command -ScriptBlock $code -ComputerName 
    • 10 Jan 2018
  • Using Group-Object to Separate Remoting Results

    When you need to get information from multiple computers via PowerShell remoting, you could query each machine separately. A much faster way is to query all machines at the same time, which raises the question how you can later separate the results.

    Here is a sample (assuming PowerShell remoting is enabled in your environment):

    $serverList = 'TRAIN11','TRAIN12'
    $code = {
    # get results…
    • 9 Jan 2018
  • Converting Numeric Strings

    Converting a string that contains a number is trivial in PowerShell:

    PS C:\> [double]"77.234"
    PS C:\>

    If the string contains a number format that is not a pure number, though, things become a challenge. If you receive a string like “2763MB” for example, PowerShell cannot automatically cast this to a number. Instead, you would need a converter function like this one:

    function Co…
    • 8 Jan 2018
  • Using Default Parameter Values

    You may have heard about PowerShell default parameter values and $PSDefaultParameterValues. When you assign a hash table to this special variable, the key defines the commands and parameters affected, and the value defines your new default value.

    Take a look at this example:

    $PSDefaultParameterValues = @{
        '*:ComputerName' = 'testserver1'

    This would set the -ComputerName parameter for all commands…

    • 5 Jan 2018
  • Correctly Importing Excel CSV Files

    If you have exported an Excel sheet to CSV and would like to import this file into PowerShell, here is how to do this:

    $path = 'D:\sampledata.csv'
    Import-Csv -Path $path -UseCulture -Encoding Default

    The important options are –UseCulture (to automatically use the same delimiter that Excel used on your system) and –Encoding Default (only with this settings will all special characters stay intact).…

    • 4 Jan 2018
  • Supporting Risk Mitigation in PowerShell Functions

    When a PowerShell function performs system changes that may be risky, it is worth supporting the –WhatIf and –Confirm risk mitigation parameters. Here are the basic requirements:

    function Test-WhatIf
        if ($PSCmdlet.ShouldProcess($env:COMPUTERNAME,"Say 'Hello'"))
    • 3 Jan 2018
  • Binding Parameters by Data Type

    PowerShell can automatically bind values to parameters by data type matching. Here is a sample that shows what benefit this can be. Simply run this function:

    function Test-Binding
            [Parameter(ParameterSetName='Integer', Position=0, Mandatory=$true)]
            [Parameter(ParameterSetName='String', Position=0,
    • 2 Jan 2018
  • Deleting Environment Variables

    In the previous tip we explained how you can set environment variables in all available scopes. But how would you remove environment variable?

    Coincidentally, you can do that the same way, simply by providing an empty string as value. However, the function from our previous tip will not accept empty strings for the -VariableValue parameter:

    function Set-EnvironmentVariable
    • 1 Jan 2018
  • Setting Environment Variables

    Occasionally you see scripts that use Select-Object to append information to existing objects. This can look similar to the code below:

    Get-Process | 
        Select-Object -Property *, Sender|
        ForEach-Object { 
            $_.Sender = $env:COMPUTERNAME

    It does work, but Select-Object creates a complete object copy, so this approach is slow and changes the object type. You’ll notice that PowerShell no longer…

    • 29 Dec 2017
  • Appending the Clipboard

    PowerShell 5 introduces cmdlets to copy text to the clipboard, and paste it back: Set-Clipboard and Get-Clipboard.

    Set-Clipboard also supports the –Append parameter that enables you to add more text to the clipboard. This can be an unconventional yet useful way of logging what a script does:

    Set-ClipBoard "Starting at $(Get-Date)"
    1..30 |
      ForEach-Object {
        Set-ClipBoard -Append "Iteration $_"…
    • 28 Dec 2017
  • Deleting User Profiles

    Whenever a user logs on to your computer, a user profile is created, and in the previous tip we explained how PowerShell can dump a list of user profiles found on a computer.

    If you’d like to get rid of a user account, PowerShell can wipe it for you. Here is how:

    First, adjust the $domain and $username variables to point to the user profile that you would like to delete. Next, run the code below in a PowerShell…

    • 27 Dec 2017
  • Managing User Profiles

    To dump the raw list of user profiles on a machine, use the following line:

    Get-CimInstance -Class Win32_UserProfile | Out-GridView

    You will get detailed information about all user profiles. The user name can be found in the property SID, however it is in SID format. To get the real user name, the SID would need to be translated. This chunk of code produces a hash table that uses the real user names as key:

    • 26 Dec 2017
  • Running Commands on Multiple Computers in Parallel

    Provided you have enabled PowerShell remoting (see our previous tips), you can easily run commands and scripts on many computers at the same time.

    The example below illustrates this, and places a text file on the desktop of all users on the listed computers. Warning: this is a very powerful script. It executes anything you place in $code on all listed machines, provided remoting is enabled, and you have proper permissions…

    • 25 Dec 2017
  • Accessing Remote Machines via PowerShell Remoting

    Once you have enabled PowerShell remoting on a target machine, try and connect to it interactively. Here is a line you should try. Just make sure you replace “targetComputerName” with the name of the target computer you want to connect to:

    PS C:\> Enter-PSSession -ComputerName targetComputerName
    [targetComputerName]: PS C:\Users\User12\Documents> $env:COMPUTERNAME
    • 22 Dec 2017
  • Playing with PowerShell Remoting

    If you’d like to test-drive PowerShell remoting, you need to enable it at least on the target machine (the one you’d like to visit). For this, you need local Administrator privileges on the target machine. Open PowerShell with Administrator privileges, and run the code below:

    #requires -RunAsAdministrator
    # manually enable PowerShell remoting
    Enable-PSRemoting -SkipNetworkProfileCheck -Force

    Next, from any…

    • 21 Dec 2017
  • Loading and Saving Options in JSON Format

    If you’d like to persist information in your script, you might want to save your data as an object in JSON format. Here is an example:

    # define options object
    $options = [PSCustomObject]@{
        Color = 'Red'
        Height = 12
        Name = 'Weltner'
    # play with options settings
    $options.Color = 'Blue'
    # save options to file
    $Path = "c:\test\options.json"
    $options | ConvertTo-Json
    • 20 Dec 2017
  • Joining Computers to a Domain

    Here are the basic steps how PowerShell can join a computer to an AD domain:

    # do not store passwords in production solutions,
    # or you MUST control access permissions to this sensitive data
    $username = "mydomain\UserName"
    $password = 'Password' | ConvertTo-SecureString -AsPlainText -Force
    $domainName = 'NameOfDomain'
    # convert username and password to a credential
    $cred = [PSCredential]::n…
    • 19 Dec 2017
  • Execution Policy Override

    If PowerShell won’t let you run a script, you may have to enable script execution first, for example like this:

    Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass -Force

    This won’t work when execution policy was defined at GPO level, because GPO settings always have a higher precedence:

    PS C:\> Get-ExecutionPolicy -List
            Scope ExecutionPolicy
            ----- ---------------
    • 18 Dec 2017
  • Formatting Text Output

    If you’d like to nicely format output text, you may want to use a PSCustomObject and output it as a formatted list like so:

    $infos = [PSCustomObject]@{
        Success = $true
        Datum = Get-Date
        ID = 123
    Write-Host ($infos| Format-List | Out-String) -ForegroundColor Yellow

    Simply add and adjust keys and values in your hash table.

    Twitter This Tip! ReTweet this Tip!

    • 15 Dec 2017
  • Converting User Name to SID

    If you’d need to find out the SID for a user name, here is a useful chunk of code that does the job:

    $domain = 'MyDomain'
    $username = 'User01'
    $sid = (New-Object Security.Principal.NTAccount($domain, $username)).Translate([Security.Principal.SecurityIdentifier]).Value

    Just make sure you adjust domain name and username accordingly. If you need to find the SID for local accounts, set the domain…

    • 14 Dec 2017
  • Test-Drive PowerShell 6 – Side by Side

    PowerShell 6 can be downloaded and run side-by-side with the official Windows PowerShell. If you’d like to test-drive it, head over to https://github.com/PowerShell/PowerShell/releases, and pick the release that suits your platform.

    Be aware that it is a hefty 50MB download. After unpacking/installing the release, there will be a new PowerShell icon in all black, representing PowerShell 6. The name has changed as…

    • 13 Dec 2017
  • Displaying Data in a Grid View Window Vertically

    Out-GridView always produces a table with one object per line:

    Get-Process -Id $pid | Out-GridView

    Occasionally, it would be more helpful to display the object properties vertically, with one property per line in a grid view window.

    To do exactly that, take a look at Flip-Object: this function takes objects and splits them up into individual name-value-objects per property. They can then pipe to Out-GridView. This way…

    • 12 Dec 2017