HTML Encoding Advanced

The static .NET method HtmlEncode does a good job encoding the usual character codes but fails with many special characters. To encode all characters correctly, here is a function called ConvertTo-EncodedHtml:

function ConvertTo-EncodedHTML($HtmlText)
{
   
  $chars = [Web.HttpUtility]::HtmlEncode($HtmlText).ToCharArray()
  $txt = New-Object System.Text.StringBuilder
  $null = . {
      foreach($c in $chars)
      {
        if ([int]$c -gt 127) 
        {
          $txt.Append("&#" + [int]$c + ";")
        }
        else
        {
          $txt.Append($c)
        }
   }
   }
   return $txt.ToString()
}

This function checks all characters with ASCII code greater than 127 and converts these characters to encoded versions:

 
PS> Convert-EncodedHTML -HtmlText "A – s ‘Test’"
A – s  ‘Test’
 

Twitter This Tip! ReTweet this Tip!

HTML Encoding

There is a static .NET method that you can use to HTML-encode text, for example if you want the text to display correctly in HTML output:

 
PS>  [System.Web.HttpUtility]::HtmlEncode('Österreich heißt so.')
Österreich heißt so.
  

Twitter This Tip! ReTweet this Tip!

Bulk Printing Word Documents

This line finds all Word documents in your profile:

Get-ChildItem -Path $home -Filter *.doc* -Recurse 

If you’d like, you can easily print them all. Here is how:

Get-ChildItem -Path $home -Filter *.doc* -Recurse |
  ForEach-Object {
    Start-Process -FilePath $_.FullName -Verb Print -Wait
  }

The most important part of this is the –Wait parameter: if you omit it, PowerShell would try and print all documents in parallel, launching many instances of Word at the same time. This can easily exhaust your system resources. With -Wait, PowerShell waits for Word to end a print before launching the next.

Twitter This Tip! ReTweet this Tip!

Downloading Videos From German Media Databases

In Germany, there are publicly available media databases with most of the TV content broadcasted by public stations. It just takes very little PowerShell code to extract the JSON data, display the TV shows in a list, and let you select some for download.

Note however that the JSON file with the download URLs is quite large, so it may take a moment for the video list to appear.

#requires -Version 3.0

# here is the list of download URLs - get it and 
# convert the JSON format
$url = 'http://www.mediathekdirekt.de/good.json'
$web = Invoke-WebRequest -Uri $url -UseBasicParsing 
$videos = $web.Content | ConvertFrom-Json 

# get all videos, create a nice title to display,
# and attach the original data to each entry
$videos |
ForEach-Object {
  $title = '{0} - {1}' -f $_[2], $_[5]
  $title | Add-Member -MemberType NoteProperty -Name Data -Value $_ -PassThru
} |
Sort-Object |
Out-GridView -Title 'Video' -OutputMode Multiple |
ForEach-Object {
  # get the actual download info from the selected videos
  # and do the download
  $url = $_.Data[6]
  $filename = Split-Path -Path $url -Leaf
  # videos are saved into your TEMP folder unless you
  # specify a different folder below
  $filepath = Join-Path -Path $env:temp -ChildPath $filename
  Invoke-WebRequest -Uri $url -OutFile $filepath -UseBasicParsing
  Invoke-Item -Path $filepath
}

Twitter This Tip! ReTweet this Tip!

Translating Error Records

Whenever PowerShell records an error, it wraps it in an Error Record object. Here is a function that takes such an error record and extracts the useful information:

#requires -Version 3.0
function Get-ErrorDetail
{
  param
  (
    [Parameter(Mandatory,ValueFromPipeline)]
    $e
  ) 
  process
  {
    if ($e -is [Management.Automation.ErrorRecord])
    {
      [PSCustomObject]@{
        Reason    = $e.CategoryInfo.Reason
        Exception = $e.Exception.Message
        Target    = $e.CategoryInfo.TargetName
        Script    = $e.InvocationInfo.ScriptName
        Line      = $e.InvocationInfo.ScriptLineNumber
        Column    = $e.InvocationInfo.OffsetInLine
        Datum     = Get-Date
        User      = $env:USERNAME
      }
    }
  }
}

So if you’d like to know what your latest errors were, try this:

 
PS C:> $error | Get-ErrorDetail | Out-GridView

PS C:>
 

Or, you can now easily ask a cmdlet to cache its errors, and evaluate them later. This example recursively searches the Windows folder for PowerShell scripts. You get the results, plus you get detailed information about any error that occurred while searching:

$files = Get-ChildItem -Path c:Windows -Filter *.ps1 -Recurse -ErrorAction SilentlyContinue -ErrorVariable myErrors

$myErrors| Get-ErrorDetail | Out-GridView

Twitter This Tip! ReTweet this Tip!

Enable AD Users with Out-GridView

Sometimes it requires just a couple of lines of code in PowerShell to produce highly useful helpdesk tools. Here is one that displays all currently disabled AD users. You can select one (or many by holding CTRL), and once you click OK, these users will be enabled:

#requires -Version 3.0 -Modules ActiveDirectory
Search-ADAccount -AccountDisabled |
  Out-GridView -Title 'Who should be enabled?' -OutputMode Multiple |
  # remove -WhatIf to actually enable accounts
  Enable-ADAccount -WhatIf

Twitter This Tip! ReTweet this Tip!