• Downloading Data via SSL and Invoke-WebRequest

    Invoke-WebRequest can download files for you but may struggle with HTTPS URLs. To use SSL connections, you may have to change a default setting. Here is a working example:

    $url = 'https://mars.nasa.gov/system/downloadable_items/41764_20180703_marsreport-1920.mp4'
    $OutFile = "$home\desktop\video.mp4"
    $AllProtocols = [Net.SecurityProtocolType]'Ssl3,Tls,Tls11,Tls12'
    • 14 Sep 2018
  • Finding Disabled GPOs

    Here is a quick one-liner that dumps all Group Policy objects that have all settings disabled:

    Get-Gpo -All | Where-Object GpoStatus -eq AllSettingsDisabled

    This sample requires the free RSAT tools from Microsoft.

    Twitter This Tip! ReTweet this Tip!

    • 14 Sep 2018
  • Browsing All Event Logs

    Get-EventLog always requires you to specify exactly one event log via -LogName. You cannot use wildcards, and you cannot browse all event logs at once.

    However, here is a trick you can do:

    PS> Get-EventLog -LogName *
      Max(K) Retain OverflowAction        Entries Log                                                         
      ------ ------ --------------        ------- ---                                           …
    • 12 Sep 2018
  • Creating Event Log Reports

    You probably have used Get-EventLog frequently to dump event log information, for example:

    PS> Get-EventLog -LogName System -EntryType Error -Newest 6
       Index Time          EntryType   Source                 InstanceID Message
       ----- ----          ---------   ------                 ---------- -------
        5237 Jul 31 12:39  Error       DCOM                        10016 The des...
        5234 Jul 31 09:54  Error    …
    • 11 Sep 2018
  • Keyboard Shortcuts for PowerShell Console

    The PowerShell console starting in version 5 ships with a module called PSReadLine which does much more than just coloring command tokens. It comes with a persistent command history, and also can bind custom commands to keyboard shortcuts.

    Take a look at this example:

    Set-PSReadlineKeyHandler -Chord Ctrl+H -ScriptBlock { 
      Get-History | 
      Out-GridView -Title 'Select Command' -PassThru | 
    • 10 Sep 2018
  • Using SSH from PowerShell

    PowerShell 6 (PowerShell Core) finally ships with SSH support: you can use SSH to connect to non-Windows machines for PowerShell remoting operations.

    To just connect to switches and other devices using SSH, there is a free module available that adds a vast of useful new SSH commands to any PowerShell. This is how you’d download and install the module:

    Install-Module -Name posh-ssh -Repository PSGallery -Scope C…
    • 7 Sep 2018
  • Managing Lenovo BIOS Settings (Part 4)

    In the previous tip we showed how you can read and change BIOS settings for Lenovo computers. This was the code to disable WakeOnLan, for example:

    #requires -RunAsAdministrator
    $currentSetting = Get-WmiObject -Class Lenovo_SetBiosSetting -Namespace root\wmi $currentSetting.SetBiosSetting('WakeOnLAN,Disable').return $SaveSettings = Get-WmiObject -Class Lenovo_SaveBiosSettings -Namespace root\wmi $SaveSetting…
    • 6 Sep 2018
  • Managing Lenovo BIOS Settings (Part 3)

    In the previous tip we explained how to manage Lenovo BIOS settings from PowerShell. Typically, there are single settings that need to be managed. Please note that you need Administrator privileges for some of the operations.

    Here is code that dumps the names of all available settings. Note that these names are case-sensitive:

    $currentSetting = Get-WmiObject -Class Lenovo_BiosSetting -Namespace root\wmi 
    • 5 Sep 2018
  • Managing Lenovo BIOS Settings (Part 2)

    In the previous tip, we explained how to dump all BIOS settings for Lenovo computers. To change settings, you need to know the supported alternatives for a given setting. Here is a chunk of code that dumps the list of available options for a given BIOS settings (for Lenovo computers):

    #requires -RunAsAdministrator
    # this is case-sensitive
    $Setting = "WakeOnLAN"
    $selections = Get-WmiObject -Class Lenovo_Ge…
    • 4 Sep 2018
  • Managing Lenovo BIOS Settings (Part 1)

    There is unfortunately no standardized way of managing BIOS settings for computer vendors. Each vendor employs proprietary approaches. For Lenovo computers, you can use WMI to access and dump BIOS settings:

    Get-WmiObject -Class Lenovo_BiosSetting -Namespace root\wmi | 
    Where-Object CurrentSetting |
    ForEach-Object {
        $parts = $_.CurrentSetting.Split(',')
            Setting = $parts[0]
    • 3 Sep 2018
  • Exploring PowerShell Modules

    Most cmdlets and functions are part of PowerShell modules. If you’d like to explore where exactly these commands come from, here is an easy approach.

    # replace the command name with any PowerShell command name
    # you'd like to explore
    $Name = "Get-Printer"
    $ModuleName = (Get-Command -Name $Name -CommandType Function, Cmdlet).Source
    if ('' -eq $ModuleName)
        Write-Warning "$Name was defined…
    • 31 Aug 2018
  • Locking Workstation

    If you’d like to lock the current workstation from within PowerShell, you can take advantage of the fact that PowerShell can run executables. Here is a quick function that uses rundll32.exe to call an internal Windows function that locks the workstation:

    function Lock-Workstation
      rundll32.exe user32.dll,LockWorkStation

    Twitter This Tip! ReTweet this Tip!

    • 30 Aug 2018
  • Detecting WinPE

    PowerShell can run inside WinPE environments. If you’d like to detect whether your PowerShell script runs inside a WinPE environment, you can simply check whether a special registry key exists:

    function Test-WinPE
      return Test-Path -Path Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlset\Control\MiniNT

    This function returns $true if you are within a WinPE environment.

    Twitter This Tip! ReTweet this Tip!

    • 29 Aug 2018
  • Extract Specific Files from ZIP Archive

    Starting with PowerShell 5, cmdlets like Extract-Archive can extract the content of ZIP files to disk. However, you can always extract only the entire archive.

    If you’d rather like to extract individual files, you can resort to .NET methods. Here is a sample that does this:

    • It takes a ZIP file and opens it for reading
    • It identifies all files inside the ZIP file that match a given file extension
    • It extracts only…
    • 28 Aug 2018
  • Dumping ZIP Archive Content

    PowerShell comes with new cmdlets like Extract-Archive that can extract (all) files from a ZIP file container. However, there is no way to just list the content of a ZIP file.

    To do this, you can use the .NET libraries used by Extract-Archive. This code will take a ZIP file and dump its content (make sure you change the path to the ZIP file to a file that exists):

    # adjust this to a valid path to a ZIP file
    $Path = "…
    • 27 Aug 2018
  • Validating Variable Content

    Beginning in PowerShell 5, you can assign a validator to a variable. The validator can take a regular expression, and once you assign new values to the variable, the validator checks to see whether the new content matches the regular expression pattern. If not, an exception is thrown, and the variable content stays untouched.

    Here is an example showing a variable that stores MAC addresses:

    • 24 Aug 2018
  • Using Profile Scripts

    PowerShell by default “forgets” most settings on restart. If you’d like to “keep” settings, you use a profile script. That’s an auto start script that runs whenever PowerShell starts. You can add whatever commands you like to this script.

    This line will open your current PowerShell profile script, and if there is none yet, notepad offers to create one for you:

    PS C:\> notepad 
    • 23 Aug 2018
  • Optimizing Command Completion

    The PowerShell console (powershell.exe, pwsh.exe) offers extensive completion support. When you enter a command and then add a space and a hyphen, pressing TAB will cycle through the available parameters.

    There is a substantial difference though between Windows PowerShell (powershell.exe) and PowerShell on Linux and macOS (pwsh.exe). When you press TAB on the latter, they show all available options at once, and you can…

    • 22 Aug 2018
  • Reading Registry Remotely (Part 2)

    In the previous example we showed the code required to read registry values remotely from another machine using the old-fashioned DCOM protocol.

    If you can use PowerShell remoting, things become much easier. You now can simply take code that would run locally on your machine, and “beam” it over to the target machine(s):

    # adjust this to a remote computer of your choice
    # (or multiple computers, comma-separated…
    • 21 Aug 2018
  • Reading Registry Remotely (Part 1)

    If you cannot use PowerShell remoting, and you need to read registry values from another system via DCOM, here is some example code you might want to try:

    $ComputerName = 'pc01'
    # NOTE: RemoteRegistry Service needs to run on a target system!
    $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $ComputerName)
    $key = $reg.OpenSubKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Unins…
    • 20 Aug 2018
  • Hardening PowerShell Script Block Logging Log

    When you enable ScriptBlockLogging, PowerShell logs all PowerShell code that is executed on your machine. Even if it is disabled, any security-relevant code is still logged. That’s awesome. However, the log can be read by any user, so anyone could browse through the logged code like this:

    Get-WinEvent -FilterHashtable @{ ProviderName="Microsoft-Windows-PowerShell";  Id = 4104 } 

    To harden security and…

    • 17 Aug 2018
  • Manipulating Registry User Hive

    Reading and writing values to the HKEY_LOCAL_USER hive in the registry is easy, because this hive is the same for all users. How would you read or write values the HKEY_CURRENT_USER hive for a user that is not you?

    Let’s assume you are admin and want to add registry values to the HKEY_CURRENT_USER hive of another user.

    First you need to mount the user hive of that person. That hive is located in the NTUSER.DAT file…

    • 16 Aug 2018
  • Managing Windows Features (Part 2)

    In Windows 10, unlike in Windows Server, you cannot use the Get-WindowsFeature and Add-WindowsFeature cmdlets to manage Windows features.

    However, for clients there is a very similar cmdlet available: Enable-WindowsOptionalFeature. These lines would add the PowerShell Hyper-V cmdlets and the Hyper-V features:

    Enable-WindowsOptionalFeature -Online -All -FeatureName Microsoft-Hyper-V-Management-PowerShell -NoRestart
    • 15 Aug 2018
  • Managing Windows Features (Part 1)

    Windows 10 comes with a vast number of features, and only a subset is installed. Manually, you would open Control Panel and look at the Windows Feature list. Experienced Administrators may also use the dism.exe command-line tool.

    With PowerShell, you can view the state of Windows features via Get-WindowsOptionalFeature. When you specify –Online, the cmdlet returns the currently available features and their states.…

    • 14 Aug 2018
  • Running CMD commands in PowerShell

    PowerShell by default does not support the native cmd.exe command such as „dir“. Instead, it uses historic aliases called “dir” to point you to the closest PowerShell cmdlet:

    PS C:\> Get-Command -Name dir | ft -AutoSize
    CommandType Name                 Version Source
    ----------- ----                 ------- ------
    Alias       dir -> Get-ChildItem 

    This explains why “dir” in PowerShell…

    • 13 Aug 2018