• 22 Aug 2017

    A better Get-History

    When you type “h” in PowerShell, you see the history of commands you entered during your session. Inspired by Pratek Singh (https://geekeefy.wordpress.com/2017/06/20/powershell-get-history/), here is a clever alternative called “h+” that opens up a grid view window instead and lets you pick the commands from your history. Hold CTRL to select multiple items. Pratek invoked all selected items using...
    • 21 Aug 2017

    Getting MAC Vendor List

    Prateek Singh has invested some effort in creating a sanitized MAC vendor address list in CSV format which can be found in his blog ( https://geekeefy.wordpress.com/2017/07/06/get-mac-vendor-using-powershell/ ). Such lists can be very useful to identify the vendor of network devices by looking at their MAC addresses. Using PowerShell, you can easily download it to your computer: #requires -Version 3.0 $url = '...
    • 18 Aug 2017

    Creating Excel Reports (Part 3 – Individually Accessing Workbook)

    Sometimes you may want to create irregularly shaped reports, that is reports in a non-table design. For this, PowerShell lets you connect to the Excel object model. This way, you can access individual cells, read and write their content, and even format them. This gives you maximum flexibility. However, the drawback is that it requires a lot of code since you have to manually set up every single workbook cell. Also...
    • 17 Aug 2017

    Creating Excel Reports (Part 2 – Colorful)

    When you load CSV data into Excel, you cannot specify formatting, fonts or colors. This is different when you load HTML data into Excel. Here is an example that illustrates how easy it can be to create a formatted and colorful Excel report, provided the report has a table design: #requires -Version 2.0 $html = & { ' <table> ' ' <tr><th>Name</th><th>Status</th><...
    • 16 Aug 2017

    Creating Excel Reports (Part 1 – Black and White)

    The most simple way of creating Excel reports requires just a couple of lines of PowerShell code: dump the results to a CSV file, then submit it as an argument to Excel: #requires -Version 2.0 $timestamp = Get-Date -Format ' yyyy-MM-dd HH-mm-ss ' $Path = " $env:temp\Excel Report $timestamp.csv " Get-Service | Export-Csv -Path $Path -Encoding UTF8 -UseCulture -NoTypeInformation Start-Process...
    • 15 Aug 2017

    Creating HTML Reports (Part 5 – Applying Style and Design)

    In the previous tip we started to turn PowerShell results into HTML reports. The report content is now just fine. To impress people, the report just needs some design improvements. This is where we left off: #requires -Version 2.0 $Path = " $env:temp\eventreport.htm " $today = Get-Date $startDate = $today . AddHours ( - 48 ) $startText = $startDate . ToString ( ' MMMM dd yyyy, HH:ss ' ) $endText...
    • 14 Aug 2017

    Creating HTML Reports (Part 4 – Renaming Columns)

    In the previous tip we started to turn PowerShell results into HTML reports. The report content is now almost done. You just may want to polish some of the column headers and rename them. This is where we left off: #requires -Version 2.0 $Path = " $env:temp\eventreport.htm " $today = Get-Date $startDate = $today . AddHours ( - 48 ) $startText = $startDate . ToString ( ' MMMM dd yyyy, HH:ss '...
    • 11 Aug 2017

    Creating HTML Reports (Part 3 – Adding Headers and Footers)

    In the previous tip we started to turn PowerShell results into HTML reports. It now needs some headers and footers. This is where we left off: #requires -Version 2.0 $Path = " $env:temp\eventreport.htm " $startDate = ( Get-Date ) . AddHours ( - 48 ) $replacementStrings = @ { Name = ' ReplacementStrings ' Expression = { $_ . ReplacementStrings -join ' , ' } } Get-EventLog -LogName...
    • 10 Aug 2017

    Creating HTML Reports (Part 2 – Fixing Non-String Content)

    In the previous tip we started to turn PowerShell results into HTML reports. So far, the report is produced but still looks ugly. This is where we start: #requires -Version 2.0 $Path = " $env:temp\eventreport.htm " $startDate = ( Get-Date ) . AddHours ( - 48 ) Get-EventLog -LogName System -EntryType Error -After $startDate | Select-Object -Property EventId , Message , Source , InstanceId , TimeGenerated...
    • 9 Aug 2017

    Creating HTML Reports (Part 1 – Creating HTML)

    To turn PowerShell results in a HTML report, simply pipe the results to ConvertTo-Html, then save the result to file. So in its most basic form, it would look like the code below. It creates a report with all event log system errors that occurred in the past 48 hours: #requires -Version 2.0 # store report here $Path = " $env:temp\eventreport.htm " # set the start date $startDate = ( Get-Date ) . AddHours...
    • 8 Aug 2017

    Control Console Transparency on Windows 10

    On Windows 10, when you open a PowerShell console, simply hold CTRL+SHIFT, then turn your mouse wheel, to control console background transparency. For this to work, in the console properties, the option “Use Legacy Console” must not be turned on. You can open the console properties by clicking the application icon on the left side of the console title bar, and then choose “Properties”. ReTweet...
    • 7 Aug 2017

    Finding Installed Updates (and searching for missing) (Part 4)

    Sometimes, the Microsoft.Update.Session object is used to check whether a given update is present on a machine. Some authors query the text title string of updates like this: #requires -Version 3.0 function Get-UpdateInstalled([Parameter(Mandatory)]$KBNumber) { $Session = New-Object -ComObject "Microsoft.Update.Session" $Searcher = $Session . CreateUpdateSearcher () $historyCount = $Searcher . GetTotalHistoryCount...
    • 4 Aug 2017

    Finding Installed Updates (and searching for missing) (Part 3)

    When you want to examine installed updates on your machine, rather than searching for updates online and then comparing the installation status with your locally installed updates, a much faster approach queries the local update history. The code below returns all updates present on your machine. It does not need an online connection. #requires -Version 2.0 $Session = New-Object -ComObject "Microsoft.Update...
    • 3 Aug 2017

    Finding Installed Updates (and searching for missing) (Part 2)

    When PowerShell asks Windows for updates via the Microsoft.Update.Session object, some information seems to be unreadable. The code below dumps information about installed updates. The property “KBArticleIDs”, however, just displays “ComObject”. #requires -Version 2.0 $Session = New-Object -ComObject Microsoft.Update.Session $Searcher = $Session . CreateUpdateSearcher () $updates = $Searcher...
    • 2 Aug 2017

    Finding Installed Updates (and searching for missing) (Part 1)

    Windows can automatically determine the updates that may be missing on your system, provided you have an Internet connection. PowerShell can use the same system interfaces to query this information. The code below returns information about all updates installed on your system: #requires -Version 2.0 $Session = New-Object -ComObject Microsoft.Update.Session $Searcher = $Session . CreateUpdateSearcher () $updates...
    • 1 Aug 2017

    Auto-Logging Command Output

    In the previous tip we introduced the PreCommandLookupAction supported by PowerShell 3 and better. Today we have a special implementation for you. When you run below code, PowerShell will accept any command that starts with “*” and log the command output in a text file. The text file opens after the command is done. So you can now run *dir instead of dir to log the results, or *Get-Process instead of Get...
    • 31 Jul 2017

    Replacing Commands

    PowerShell comes with a couple of “secret” (better: under-documented) settings. One is PreCommandLookupAction, and it gives you great power: this action is executed whenever PowerShell is ready to execute a command. Your event handler can now adjust, change, or manipulate both the original command and the arguments submitted to it. Today we’ll be using this simply to secretly exchange a command with...
    • 28 Jul 2017

    Easy Parsing of Setting Files (Part 3)

    In the previous tip you have discovered how ConvertFrom-StringData can turn plain text key-value pairs into a hash table. What’s missing is the other way: turn a hasht able into plain text. With that in place, you’d have a really simple framework to save settings and information to files. Let’s first create a hash table with some data: $test = @ { Name = ' Tobias ' ID = 12 Conf = '...
    • 27 Jul 2017

    Easy Parsing of Setting Files (Part 2)

    In the previous tip we used ConvertFrom-StringData to parse plain text key-value pairs into hash tables. Here is an example where such conversion fails: $settings = @' Machine=Server12 Path=c:\test '@ $settings | ConvertFrom-StringData When you look at the result, you’ll quickly see why: Name Value ---- ----- Machine Server12 Path c: est Apparently, ConvertFrom-StringData treats “...
    • 26 Jul 2017

    Easy Parsing of Setting Files (Part 1)

    Let’s assume you want to save settings to a file in the most simplest form. Your settings may look like this: $settings = ' Name = Weltner FirstName = Tobias ID = 12 Country = Germany Conf = psconf.eu ' You could save these settings to file using Set-Content, and read them back using Get-Content. Yet how would you parse the information so that you can access individual items? There is...
    • 25 Jul 2017

    Adding Live Clock to PowerShell Title Bar (Part 2)

    In the previous tip we presented code that would update the PowerShell title bar in a background thread, displaying a live clock. Wouldn’t it be nice to also show the current path location? The challenge: how would the background thread know the current path of the foreground PowerShell? There is a PowerShell variable called $ExecutionContext which provides all kinds of useful information on the state of a context...
    • 24 Jul 2017

    Adding Live Clock to PowerShell Title Bar (Part 1)

    To continuously update the PowerShell title bar, and for example display the current date and time, you need a background thread that takes care of this. Without a background thread, your PowerShell would be busy all the time updating the title bar, thus unusable. Here is a simple piece of code you can run to display a live clock in your title bar: $code = { # submit the host process RawUI interface and the execution...
    • 21 Jul 2017

    When Add-Type Fails…

    Add-Type can be used to load additional .NET assemblies from DLL files into PowerShell. This works well most of the time, and here is a sample call (that would require the SharePoint DLL to be available of course): PS> Add-Type -Path "C:\SharepointCSMO\Microsoft.SharePoint.Client.dll" With some DLL files, this fails though, and PowerShell returns an exception saying “Unable to load one or more...
    • 20 Jul 2017

    Understanding PowerShell and System Paths

    PowerShell maintains its own current location: PS> Get-Location Path ---- C:\Users\tobwe The current location applies to relative paths used with any cmdlet. PS> Get-Location Path ---- C:\Users\tobwe PS> Resolve-Path -Path . Path ---- C:\Users\tobwe There is another current path, maintained by Windows, that applies to all .NET methods. It may be different than PowerShell’s current...
    • 19 Jul 2017

    Finding PowerShell’s Current File System Path

    To find out the path your PowerShell is currently using, simply run Get-Location: PS> Get-Location Path ---- C:\Users\tobwe However, the current path does not necessarily point to a files system location. If you changed location to the registry, for example, it looks like this: PS> cd hkcu:\ PS> Get-Location Path ---- HKCU:\ If you need to know the current file system path PowerShell uses...