• 16 Jun 2017

    Setting Time Zone

    While you need administrative privileges to adjust time and date on your computer, each user can change the time zone, i.e. when you travel. PowerShell 5 comes with a very simple family of cmdlets to manage time zones. First, check out your current setting: PS> Get-TimeZone Id : W. Europe Standard Time DisplayName : (UTC+01:00) Amsterdam, Berlin, Bern, Rom, Stockholm, Wien StandardName : Mitteleuropäische...
    • 15 Jun 2017

    Finding All Variables in a Script

    In the previous tip we illustrated how you can analyze the content of a script block and search for variables or commands. The same is possible for text-based scripts. The script below will analyze itself and dump variables and commands: $filepath = $PSCommandPath $tokens = $errors = $null $ast = [ System.Management.Automation.Language.Parser ] :: ParseFile ( $filepath , [ ref ] $tokens , [ ref ] $errors ) #...
    • 14 Jun 2017

    Finding All Variables in a Script Block

    To analyze the content of a script block, you can easily examine the AST, and, for example, create a list of all variables in the code: $code = { $a = "Test" $b = 12 Get-Service Get-Process $berta = 100 } $code . Ast . FindAll ( { $true } , $true ) | Where-Object { $_ . GetType () . Name -eq ' VariableExpressionAst ' } | Select-Object -Property VariablePath -ExpandProperty Extent...
    • 13 Jun 2017

    Running PowerShell Script as a Scheduled Task

    If you need to run a PowerShell script in regular intervals, why not run it as a scheduled task? Here are some lines that help you create a new scheduled task to run a PowerShell script at 6AM: #requires -Modules ScheduledTasks #requires -Version 3.0 #requires -RunAsAdministrator $TaskName = ' RunPSScriptAt6 ' $User = "train\tweltner" $scriptPath = "\\Server01\Scripts\find-newaduser.ps1"...
    • 12 Jun 2017

    Spying on Function Source Code

    Here is a quick way how to find the source code of PowerShell functions: $ { function : Clear - Host } | clip This would copy the Clear-Host source code to the clipboard, and when you paste it, you’ll see how Clear-Host works: $RawUI = $Host . UI . RawUI $RawUI . CursorPosition = @ { X = 0 ;Y = 0 } $RawUI . SetBufferContents ( @ { Top = -1 ; Bottom = -1 ; Right = -1 ; Left = -1 } , @ { Character =...
    • 9 Jun 2017

    Modern Alternative to More

    In a PowerShell console, you can continue to pipe to more, just like in cmd.exe, to view results page by page. However, more does not support real-time pipelining, so all data needs to be collected first. This can take a long time and burn much memory: dir c:\windows -Recurse -ea 0 | more A better way is to use PowerShell’s own paging mechanism: dir c:\windows -Recurse -ea 0 | Out-Host -Paging Note that...
    • 8 Jun 2017

    Creating SMB Shares Remotely

    Here are a couple of lines that remotely create an SMB share on a server: #requires -Version 3.0 -Modules CimCmdlets, SmbShare -RunAsAdministrator $computername = ' Server12 ' $shareName = ' ScriptExchange ' $fullAccess = ' domain\groupName ' $session = New-CimSession -ComputerName $computername New-SMBShare -Name $shareName -Path c:\Scripts -FullAccess $fullAccess -CimSession $session...
    • 7 Jun 2017

    Important PowerShell Variables

    Here is a list of important PowerShell variables: $pshome is the path to the place where PowerShell lives. $home is the path to your personal profile folder. And $PSVersionTable returns the PowerShell version and the versions of important subcomponents: PS> $pshome C:\Windows\System32\WindowsPowerShell\v1.0 PS> $HOME C:\Users\tweltner PS> $PSVersionTable Name Value ---- ----- PSVersion 5.1.14393.0 PSEdition...
    • 6 Jun 2017

    Read-Host Blocks Automation

    Using Read-Host to ask for user information can be problematic because it prevents scripts from running unattended. A better way could be to wrap Read-Host in the param() block. This way, the information can be submitted via arguments for unattended operation, and prompted for interactive usage: param ( $Name = $ ( Read-Host -Prompt ' Enter your name ' ) , $Id = $ ( Read-Host -Prompt ' Enter your ID...
    • 5 Jun 2017

    Force Client Time Resync

    If your client does not sync time correctly with your domain controller, try the code below. It does require Admin privileges: w32tm.exe /resync /force ReTweet this Tip!
    • 2 Jun 2017

    Mapping Network Drives

    PowerShell offers numerous ways to connect to SMB file shares. Here are three different approaches: # adjust path to point to your file share $UNCPath = ' \\server\share ' net use * $UNCPath New-PSDrive -Name y -PSProvider FileSystem -Root $UNCPath -Persist New-SmbMapping -LocalPath ' x: ' -RemotePath $UNCPath Net.exe is the most versatile approach and available in all PowerShell versions...
    • 1 Jun 2017

    Safely Deleting Data

    To safely delete files, folders, or entire drives, PowerShell can use the built-in cipher.exe tool. This line would safely delete the old user profile: Cipher.exe / w : c:\Users\ObsoleteUser Note that the path to the folder to delete needs to be separated by a *** from the parameter /w. Clearing the data takes a while: Windows is overwriting the entire data content multiple times to ensure it cannot be recovered...
    • 31 May 2017

    Finding Organizational Units

    Get-OrganizationalUnit (from Microsofts free RSAT tools) can search for organizational units based on fully distinguished name or GUID, or you can use the –Filter parameter. Unfortunately, -Filter cannot easily be automated. The code below does not work and will not return all organizational units with “Test” in their name: $Name = ' Test ' Get-ADOrganizationalUnit -Filter { Name -like...
    • 30 May 2017

    Testing Organizational Unit

    Provided you have installed the free Microsoft RSAT tools, here is a simple way to check whether an OU exists: $OUPath = ' OU=TestOU,DC=train,DC=powershell,DC=local ' $exists = $ ( try { Get-ADOrganizationalUnit -Identity $OUPath -ErrorAction Ignore } catch {}) -ne $null "$OUPath : $exists" $exists will be $true or $false, indicating whether the OU was found. Note the use of try/catch error...
    • 29 May 2017

    Validating Variables

    Variables and function parameters can be automatically validated through validation attributes. Here is a simple example making sure $test1 can only store values between 1 and 10: [ ValidateRange ( 1 , 10 )] $test1 = 10 Once you assign a value less than 1 or greater than 10 to it, PowerShell throws an exception. You just don’t have any control over the exception text. By using a script validator, you can...
    • 26 May 2017

    Cloning DHCP Server Settings

    Beginning with Windows Server 2012, you can easily export and re-import DHCP settings. Cloning or migrating DHCP servers is a snap. The example below exports the settings from \\ORIGDHCP and imports them into the local DHCP Server: Export-DHCPServer -File " $env:temp\dhcpsettings.xml " -Computername ORIGDHCP Import-DHCPServer -File " $env:temp\dhcpsettings.xml " ReTweet this Tip!
    • 25 May 2017

    Searching for ADUsers

    The free Microsoft RSAT tools come with the PowerShell “ActiveDirectory” module: plenty of cmdlets help you administer Active Directory users and computers. One cmdlet is especially useful. Rather than trying to find AD users with Get-ADUser and complex filters, use Search-ADAccount instead. It is specialized in finding users based on common scenarios. This line, for example, finds all user accounts that...
    • 24 May 2017

    Generating Random Passwords

    Here is a very simple way to create complex random passwords: Add-Type -AssemblyName System.Web $PasswordLength = 12 $SpecialCharCount = 3 [ System.Web.Security.Membership ] :: GeneratePassword ( $PasswordLength , $SpecialCharCount ) The API call lets you choose the length of the password, and the number of non-alphanumeric characters it contains. ReTweet this Tip!
    • 23 May 2017

    ToString() Masquerade

    In the previous tip we explained that ToString() is a fuzzy way of describing an object, and that the object author can decide what ToString() returns. This is especially true for your PowerShell code. Have a look how easily you can overwrite ToString() for any object: PS> $a = 1 PS> $a | Add-Member -MemberType ScriptMethod -Name toString -Value { 'go away' } -Force PS> $a go away PS> $a.GetType...
    • 22 May 2017

    Careful with ToString()

    Any .NET object has a method ToString() that returns a text representation. This is also what you get when you output an object in a string. However, the value returned by ToString() can vary, and you should never use it to make critical assumptions. Here is an example – these lines both produce a FileInfo object which represents the exact same file. Only the way how the object was created is different. All object...
    • 19 May 2017

    Escape Wildcards

    When you use the –like operator, it supports three wildcards: “*” representing any number of any characters, “?” representing one character, and “[a-z]” for a list of characters. In addition, and this is not widely known, it supports the PowerShell escape character “`” that you can use to escape the wildcards. So when you check for “*” in a string, this...
    • 18 May 2017

    Validating Integer Variables

    You can easily assign the [Int] type to a variable to make sure it can contain only digits. But did you know that you can also apply a regex validator (at least starting in PowerShell 4)? This way, you can define that a variable should be integer but can only have numbers between 2 and 6 digits, or any other pattern you require: PS> [ValidatePattern('^\d{2,6}$')][int]$id = 666 PS> $id = 10000 ...
    • 17 May 2017

    Creating Random MAC Addresses

    If you just need a bunch of randomly generated MAC addresses, and you don’t care much about whether these addresses are actually valid, then here is a one liner: PS> (0..5 | ForEach-Object { '{0:x}{1:x}' -f (Get-Random -Minimum 0 -Maximum 15),(Get-Random -Minimum 0 -Maximum 15)}) -join ':' a5:66:07:6d:d9:18 PS> (0..5 | ForEach-Object { '{0:x}{1:x}' -f (Get-Random -Minimum 0 -Maximum...
    • 16 May 2017

    Bitwise Shift

    PowerShell contains some binary operators that are not so commonly used, for example bitwise shifting. The -shl operator shifts bits to the left: PS> 1 -shl 1 2 PS> 2 -shl 1 4 PS> 3 -shl 1 6 ReTweet this Tip!
    • 15 May 2017

    Converting Binary String to Integer

    Here is how you convert a binary text string into the corresponding integer value: $binary = "110110110" $int = [ Convert ] :: ToInt32 ( $binary , 2 ) $int Going the other way is even easier: PS> [Convert]::ToString(438,2) 110110110 ReTweet this Tip!