Blog - Post List
  • Power Tips: Finding Nested Active Directory Memberships (Part 1)

    The ActiveDirectory module (part of the free RSAT tools) provides a number of AD cmdlets. One of these can dump all direct group memberships, for example:

     
    PS> Get-ADPrincipalGroupMembership  -Identity $env:username
     

    However, the cmdlet cannot list indirect group memberships, and it also has a bug: in some scenarios, it simply reports an „Unknown Error“.

    Here is a simple alternative dumping all group…

    • 20 Jul 2018
  • Power Tips: Progress Bar Timer

    Here is a simple example using the PowerShell progress bar. The code displays a progress bar counting down a break. Simply adjust the number of seconds you’d like to pause. You could use this example for displaying breaks in classes or conferences:

    $seconds = 60
    1..$seconds |
    ForEach-Object { $percent = $_ * 100 / $seconds; 
    
    Write-Progress -Activity Break -Status "$($seconds - $_) seconds remaining..."…
    • 19 Jul 2018
  • Power Tips: Automatic Document & Report Generation (Part 5)

    Iain Brighton has created a free PowerShell module called „PScribo“ that can be used to easily create documents and reports in text, html, or Word format.

    To use this module, simply run this command:

    # https://github.com/iainbrighton/PScribo 
    # help about_document 
    
    # create a folder to store generated documents 
    $OutPath = "c:\temp\out"
    $exists = Test-Path -Path $OutPath
    if (!$exists) { $null =
    • 18 Jul 2018
  • Power Tips: Automatic Document & Report Generation (Part 4)

    Iain Brighton has created a free PowerShell module called „PScribo“ that can be used to easily create documents and reports in text, html, or Word format.

    To use this module, simply run this command:

    Install-Module -Name PScribo -Scope CurrentUser -Force
    

    In the previous tips, we explained how you can generate dynamic tables. Today, find out how you can highlight individual table cells to indicate conditions…

    • 17 Jul 2018
  • Power Tips: Automatic Document & Report Generation (Part 3)

    Iain Brighton has created a free PowerShell module called „PScribo“ that can be used to easily create documents and reports in text, html, or Word format.

    To use this module, simply run this command:

    Install-Module -Name PScribo -Scope CurrentUser -Force
    

    In the previous tips, we explained how you can generate dynamic tables. Today, we’d like to show how easy it is to adjust tables, and display arbitrary data…

    • 16 Jul 2018
  • Power Tips: Automatic Document & Report Generation (Part 2)

    Iain Brighton has created a free PowerShell module called „PScribo“ that can be used to easily create documents and reports in text, html, or Word format.

    To use this module, simply run this command:

    Install-Module -Name PScribo -Scope CurrentUser -Force
    

    Today, we are going to generate a document with dynamic table content:

    # https://github.com/iainbrighton/PScribo
    # help about_document
    
    # create a folder…
    • 13 Jul 2018
  • Power Tips: Automatic Document & Report Generation (Part 1)

    Iain Brighton has created a free PowerShell module called „PScribo“ that can be used to easily create documents and reports in text, html, or Word format.

    To use this module, simply run this command:

    Install-Module -Name PScribo -Scope CurrentUser -Force
    

    Next, you can generate simple documents like this:

    # https://github.com/iainbrighton/PScribo
    # help about_document
    
    # create a folder to store generated…
    • 12 Jul 2018
  • Power Tips: Exchanging Variable Values

    Here’s a quick tip how to switch variable content in one line:

    $a = 1
    $b = 2
    
    # switch variable content
    $a, $b = $b, $a
    
    $a
    $b
    

    Twitter This Tip! ReTweet this Tip!

    • 11 Jul 2018
  • Power Tips: Returning Rich Objects from Functions (Part 2)

    Whenever a function returns objects with more than four properties, PowerShell formats the output as list, else as table. Before you learn a new trick to influence this behavior, check for yourself. The function below returns an object with 6 properties:

    function Get-TestData 
    {
      # if a function is to return more than one information kind,
      # wrap it in a custom object
    
      [PSCustomObject]@{
          # wrap anything you…
    • 10 Jul 2018
  • Power Tips: Returning Rich Objects from Functions (Part 1)

    If a PowerShell function needs to return more than one information kind, always make sure you wrap the pieces of information inside a rich object. The easiest way to produce such a custom object is [PSCustomObject]@{} like this:

    function Get-TestData 
    {
      # if a function is to return more than one information kind,
      # wrap it in a custom object
    
      [PSCustomObject]@{
          # wrap anything you'd like to return
       
    • 9 Jul 2018
  • Power Tips: Using persisting variables inside functions

    By default, when a PowerShell function exits, it “forgets” all internal variables. However, there is a workaround that creates persisting internal variables. Here is how:

    # create a script block with internal variables
    # that will persist
    $c = & { 
        # define an internal variable that will 
        # PERSIST and keep its value even though
        # the function exits
        $a = 0
    
        {
            # use the internal…
    • 6 Jul 2018
  • Power Tips: Using Default Parameters

    If you find yourself always using the same parameter values over again, try using PowerShell default parameters. Here is how:

    # hash table
    # Key =
    # Cmdlet:Parameter
    # Value = 
    # Default value for parameter
    # * (Wildcard) can be used
    
    $PSDefaultParameterValues = @{ 
    'Stop-Process:ErrorAction' = 'SilentlyContinue' 
    '*:ComputerName' = 'DC-01'
    'Get-*:Path' = 'c:\windows'
    }
    • 5 Jul 2018
  • Power Tips: Speed Difference: Reading Large Log Files

    When it comes to reading large log files and, for example, extracting error messages, PowerShell can either use the low memory pipeline, or the high memory classical loops. The difference is not just the memory consumption, though, but also the speed.

    With the pipeline, you do not need much memory but the script may also be very slow. By using the classic loop, the script produces the same results 10x to 100x faster:

    • 4 Jul 2018
  • Power Tips: Finding Executable for File

    Most things can be handled by built-in PowerShell commands, but if that’s not enough, you can always resort to the internal Windows API. For example, if you’d like to find out what the application is that is associated with a given file, try this:

    function Get-ExecutableForFile
    {
        param
        (
            [Parameter(Mandatory)]
            [string]
            $Path
        )
    
        $Source = @"
    
    using System;
    using System…
    • 3 Jul 2018
  • Power Tips: Understanding Script Block Logging (Part 7)

    This is part 7 of our mini-series covering PowerShell script block logging. We now just need some cleanup tool that can clear the script block logging log. For this, you need Administrator privileges.

    Before you clear the log: this will clear the entire PowerShell log. If you do not own the machine, make sure it is OK to delete this information. It may be used by others for forensic security analysis.

    Here is a function…

    • 2 Jul 2018
  • Power Tips: Understanding Script Block Logging (Part 6)

    This is part 6 of our mini-series covering PowerShell script block logging, and it’s time to address a final thing: when you execute very large PowerShell scripts, they are logged in chunks (parts). What’s missing is some logic that defragments the code parts:

    function Get-LoggedCode
    {
      # to speed up SID-to-user translation,
      # we use a hash table with already translated SIDs
      # it is empty at first
      
    • 29 Jun 2018
  • Power Tips: Understanding Script Block Logging (Part 5)

    This is part 5 of our mini-series covering PowerShell script block logging. We are almost done, and what’s missing is a better way to read logged code. In our previous approach, the user who executed the code was returned as a cryptic SID instead of a clear-text name. Here’s a function that turns the user SID into a real name, and also uses a clever cache to speed up the SID lookup:

    function Get-LoggedCod…
    • 28 Jun 2018
  • Power Tips: Understanding Script Block Logging (Part 4)

    This is part 4 of our mini-series covering PowerShell script block logging. By now, you know how to read logged PowerShell code, and how to turn on verbose mode. With verbose mode turned on, any PowerShell code that executes on your machine is logged, so this may produce a lot of data. In order to not overwrite older log entries, you should enlarge the log file. Here is how:

    function Set-SBLLogSize
    {
      <#
          .S…
    • 27 Jun 2018
  • Power Tips: Understanding Script Block Logging (Part 3)

    This is part 3 of our mini-series covering PowerShell script block logging. By default, PowerShell logs only code that is considered security relevant. Today, we’ll enable verbose logging. With verbose logging turned on, any PowerShell code executed on your machine by any user will be logged.

    To enable verbose mode, you need Administrator privileges. Here is a function that enables verbose logging:

    function Enable…
    • 26 Jun 2018
  • Power Tips: Understanding Script Block Logging (Part 2)

    This is part 2 of our mini-series covering PowerShell script block logging. Today, we’ll again read the script block logging log, but this time we’ll try and get back the log data in a more useful object-oriented way:

    function Get-LoggedCode
    {
        # read all raw events
        $logInfo = @{ ProviderName="Microsoft-Windows-PowerShell"; Id = 4104 }
        Get-WinEvent -FilterHashtable $logInfo | 
           
    • 25 Jun 2018
  • Power Tips: Understanding Script Block Logging (Part 1)

    Beginning with PowerShell 5, the PowerShell engine starts to log executed commands and scripts. By default, only commands considered potentially harmful are logged. When you enable verbose logging, though, all executed code from all users on a given machine are logged.

    This is the first part of a mini series introducing you to script block logging. Today, we just want to get to the logged script code in the most basic…

    • 22 Jun 2018
  • Power Tips: Adding Leading Zeroes

    If you need numbers with leading zeroes, for example for server names, here are two approaches. First, you can turn the number into a string, then use PadLeft() to “pad” the string to the desired length:

    $number = 76
    $leadingZeroes = 8
    
    $number.Tostring().PadLeft($leadingZeroes, '0') 
    
    Or, you can use the -f operator:
    
    
    $number = 76
    $leadingZeroes = 8
    
    "{0:d$leadingZeroes}" -f $number
    

    Twitter This Tip!

    • 21 Jun 2018
  • Power Tips: Displaying Message Box

    If you’d like to show a default MessageBox with some buttons for the user to click, try this function:

    function Show-MessageBox
    {
      [CmdletBinding()]
      param
      (
        [Parameter(Mandatory=$true,ValueFromPipeline=$false)]
        [String]
        $Text,
        
        [Parameter(Mandatory=$true,ValueFromPipeline=$false)]
        [String]
        $Caption,
        
        [Parameter(Mandatory=$true,ValueFromPipeline=$false)]
        [Windows.Mess…
    • 20 Jun 2018
  • Power Tips: Displaying Input Box

    If you’d like to open a quick and dirty input box to prompt a user for some data, you could access Microsoft Visual Basic and “borrow” its InputBox:

    Add-Type -AssemblyName Microsoft.VisualBasic
    $result = [Microsoft.VisualBasic.Interaction]::InputBox("Enter your Name", "Name", $env:username)
    $result
    

    Note though that this approach has some limitations: the input box may open behind…

    • 19 Jun 2018
  • Power Tips: Reading Text Files Fast

    There are plenty of ways how PowerShell can read in text files, and they can differ considerably in time. Check for yourself. The examples below illustrate different approaches and measure the execution times. Just make sure the path in the example exists, and if not, choose a large text file to play with.

    # make sure this file exists, or else
    # pick a different text file that is
    # very large
    $path = 'C:\Windows\Logs…
    • 18 Jun 2018