• 21 Apr 2017

    Ejecting CD Drive

    Here is a fun little function that uses WMI to eject your CD drive. It does so by first asking WMI for all CD drives. It then uses the explorer object model to navigate to the drive and call its context menu item “Eject”: function Eject-CD { $drives = Get-WmiObject Win32_Volume -Filter "DriveType=5" if ( $drives -eq $null ) { Write-Warning "Your computer has no CD drives to eject."...
    • 20 Apr 2017

    Identifying CSV Delimiter

    When importing a CSV file with Import-Csv, you need to specify a delimiter, and if you pick the wrong one, import obviously fails. You need to know the delimiter a CSV file is using. Here is a simple approach that tells you the delimiter for a given CSV file: function Get - CsvDelimiter ( $Path ) { # get the header line $headerLine = Get-Content $Path | Select-Object -First 1 # examine header line per character...
    • 19 Apr 2017

    Identifying Duplicate CSV Headers (Part 2)

    When a CSV file contains duplicate column headers, it cannot be imported. In the previous tip we illustrated how you can detect duplicate column headers in a CSV file. Now here is an approach that auto-corrects duplicate entries. First, you need a CSV file with duplicate column headers. On German systems, for example, you could create one like this: PS C:\> driverquery /V /FO CSV | Set-Content -Path $env:temp...
    • 18 Apr 2017

    Identifying Duplicate CSV Headers (Part 1)

    CSV files are just text files, so it is easy to strip the first line and examine its headers. If you don’t have a CSV file at hand, here is a simple line to create one to play with: PS C:\> Get-Process | Export-Csv -Path $env:temp\test.csv -NoTypeInformation -Encoding UTF8 -UseCulture PS C:\> Now you can analyze its headers. This simple approach tells you whether there are duplicate headers in a CSV...
    • 17 Apr 2017

    Serializing Date and Time in a Culture-Invariant Way

    When you save date and time to text, for example when exporting to CSV, or when creating text reports, DateTime objects are converted to the date and time format defined in your regional settings: PS> $date = Get-Date -Date '2017-02-03 19:22:11' PS> "$date" 02/03/2017 19:22:11 PS> $date.ToString() 03.02.2017 19:22:11 PS> Get-Date -Date $date -DisplayHint DateTime Freitag, 3. Februar...
    • 14 Apr 2017

    Converting Ticks to Date and Time (Part 2)

    In the previous tip we explained how you convert date and time displayed as ticks to a true DateTime format. However, there are two different time formats involving ticks, and here is an overview of how you can convert numeric datetime information: PS> $date = Get-Date -Date '2017-02-03 19:22:11' PS> $ticks = $date.Ticks PS> $ticks 636217465310000000 PS> [DateTime]$ticks Friday, February 3,...
    • 13 Apr 2017

    Converting Ticks to Date and Time (Part 1)

    Occasionally, you may run into strange date and time representations: they might be represented as a 64-bit integer like this: 636264671350358729. If you’d like to convert these “ticks” (the smallest time and date increment on Windows), simply convert the number to a DateTime type: PS> [DateTime]636264671350358729 Thursday, March 30, 2017 10:38:55 Likewise, to turn a date into ticks, try...
    • 12 Apr 2017

    Directly Importing Certificates (Part 2)

    In the previous tip we showed how to import digital certificates with .NET methods on any version of PowerShell. Newer versions of PowerShell come with the “PKI” module which includes the cmdlet Import-Certificate. With it, importing certificates becomes even easier. #requires -Version 2.0 -Modules PKI # importing to personal store $Path = ' C:\Path\To\CertFile.cer ' Import-Certificate -FilePath...
    • 11 Apr 2017

    Directly Importing Certificates (Part 1)

    Installing certificate files on a computer can be done using .NET methods with any version of PowerShell. This would import a certificate file to your personal store: # importing to personal store $Path = ' C:\Path\To\CertFile.cer ' $Store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList My , CurrentUser $Store . Open ( ' ReadWrite ' ) $Store . Add (...
    • 10 Apr 2017

    Beware of Aliases

    Can you spot what is wrong here? PS C:\> function r { "This never runs" } PS C:\> r function r { "This never runs" } PS C:\> When you run function “r”, it simply returns the function source code. The reason is that the function name “r” conflicts with a built-in alias: PS C:\> Get-Alias r CommandType Name Version Source ----------- ---- ------- ---...
    • 7 Apr 2017

    Dealing with Long File Paths

    Historically, the Windows file system sometimes stalls when paths grow longer than 256 characters. There is a module available at the PowerShell Gallery that adds cmdlets to quickly search the file system, and support paths of any length. If you use PowerShell 5 or have installed PowerShellGet ( www.powershellgallery.com ), this is how you can download and install the “PSAlphaFS” module from the PowerShell...
    • 6 Apr 2017

    Detecting Character Code 0

    Occasionally, strings use a “Byte 0” character as a delimiter. Unlike most other delimiters, this delimiter does not show in text output but can still be used to separate the text parts. PowerShell can deal with character code 0 strings. It is represented by a backtick followed by the number 0. Note that text needs to be placed in double-quotes in order to convert the backtick sequence to byte 0. Here...
    • 5 Apr 2017

    Auto-Declaring Alias Names for Functions

    You probably know that PowerShell supports alias names for commands. But did you know that you can define alias names for PowerShell functions inside a function definition (introduced in PowerShell 4)? Have a look: function Get-AlcoholicBeverage { [ Alias ( ' Beer ' , ' Drink ' )] [ CmdletBinding ()] param () "Here is your beer." } The “official” name for the function...
    • 4 Apr 2017

    Checking Operating System Version

    Here is a simple and fast way of checking the operating system version: PS C:\> [Environment]::OSVersion Platform ServicePack Version VersionString -------- ----------- ------- ------------- Win32NT 10.0.14393.0 Microsoft Windows NT 10.0.14393.0 So now it’s a snap checking whether a script runs on the intended operating system. To check for Windows 10, for example, try this: PS C:\> [Environment...
    • 3 Apr 2017

    Comparing Against $NULL

    If you want to find out whether a variable contains $Null (nothing), always make sure you keep $null on the left side of the comparison. Most of the time, the order does not really matter: PS C:\> $a = $null PS C:\> $b = 12 PS C:\> $a -eq $null True PS C:\> $b -eq $null False However, if a variable contains an array, placing the array on the left side of the comparison operator makes it work like...
    • 31 Mar 2017

    Examining Certificate Details

    If you’d like to examine and view the details of a certificate file without the need to import it into your certificate store, here is a simple example: # replace path with actual path to CER file $Path = ' C:\Path\To\CertificateFile\test.cer ' Add-Type -AssemblyName System.Security [ Security.Cryptography.X509Certificates.X509Certificate2 ] $cert = [ Security.Cryptography.X509Certificates.X509Certificate2...
    • 30 Mar 2017

    Exporting ActiveDirectory Module

    To manage users and computers in your Active Directory from PowerShell, you need the ActiveDirectory module which comes as part of the free RSAT tools from Microsoft. Provided you are domain administrator and have remoting access to your domain controller, you can also export the ActiveDirectory module from your DC, and use it locally via implicit remoting. Here is how you do this: $DC = ' dc1 ' # rename...
    • 29 Mar 2017

    Managing NTFS Permissions

    While there are not many built-in cmdlets to manage NTFS permissions, there is a growing list of open source PowerShell modules adding these. One promising module is written by Raimund Andree, a German Microsoft engineer who will also speak at the upcoming PowerShell Conference EU ( www.psconf.eu ). If you use PowerShell 5 or have installed PowerShellGet ( www.powershellgallery.com ), this is how you can download and...
    • 28 Mar 2017

    Determine if Array Contains Value – Using Wildcards

    If you’d like to know whether an array contains a given element, PowerShell provides the –contains operator. This operator does not support wildcards, though, so you only can check for exact matches. Here is a workaround that helps you filter array elements with wildcards: $a = ' Hanover ' , ' Hamburg ' , ' Vienna ' , ' Zurich ' # is the exact phrase present in array...
    • 27 Mar 2017

    Working with LDAP and Dates

    LDAP filters are a fast and powerful way of retrieving information from Active Directory. However, LDAP filters use a very low-level date and time format. It is basically a huge integer number. Fortunately, PowerShell contains ways of converting real DateTime objects into these numbers, and vice versa. Here is a code sample that uses Get-ADUser from ActiveDirectory module to find all users who recently changed their...
    • 24 Mar 2017

    Using a PowerShell Parameter Validator

    PowerShell function parameters support a ValidateScript attribute where you can assign PowerShell code. The code is invoked when the parameter receives a value from a user, and can return $true or $false. If the code returns $false, the argument is rejected. Here is a sample that accepts file names only if the file exists in the Windows folder: function Get-File { param ( [ Parameter ( Mandatory )] [ ValidateScript...
    • 23 Mar 2017

    Casting Data with Culture

    When casting data (converting it to a different data type), PowerShell supports two approaches that can differ considerably. Here is an example: [ DateTime ] ' 12.1.2017 ' ' 12.1.2017 ' -as [ DateTime ] Both lines cast a string into a DateTime object. The first line represents a forceful cast. It will either succeed or fail, and it always uses culture-neutral format (US format), so it expects...
    • 22 Mar 2017

    Invoking a Script Block

    Code inside a script block can either be invoked by call operators such as „&“ or „.“, or by calling the Invoke() method. One difference is the output when there is more than one result: call operators return a plain object array whereas Invoke() returns a collection: $code = { Get-Process } $result1 = & $code $result2 = $code . Invoke () $result1 . GetType () . FullName $result2...
    • 21 Mar 2017

    Running Cmdlets without Verb

    This has been part of PowerShell since version 1.0: cmdlets with verb „get“ can be invoked without the verb. So instead of „Get-Service“, you can run „Service“, and instead of „Get-Date“, you can run „Date“. These are no aliases, and apparently even the PowerShell engine does not know why this works. Try running these: PS > Date PS > Get-Command Date...
    • 20 Mar 2017

    Texts with Maximum Length (Part 2)

    Here is another strategy to make sure a text does not exceed a given length. In contrast to our previous tip, this code will not pad spaces in case the text is shorter than the maximum length: $text = ' this ' $MaxLength = 10 $CutOff = [ Math ] :: Min ( $MaxLength , $text . Length ) $text . Substring ( 0 , $CutOff ) Key is the Min() method which determines the smaller of two values. ReTweet this Tip...