Replacing the Default PSRepository with your own (For PowerShell v 5.0.10586.117)


The script below is a template for changing the default PSRepository location.

#Script to change the default PSGallery URLs to custom ones (Needed for PowerShell 5.0.10586.117)
$xmlPath = "${env:APPDATA}\Microsoft\Windows\PowerShell\PowerShellGet\PSRepositories.xml" -ireplace "Roaming","Local"

$config = Import-Clixml -Path $xmlPath

$config.Item("PSGallery").SourceLocation = '<YOUR_INTERNAL_PROGET_URL_HERE>'
$config.Item("PSGallery").PublishLocation = '<YOUR_INTERNAL_PROGET_URL_HERE>'
$config.Item("PSGallery").ScriptSourceLocation = ''
$config.Item("PSGallery").ScriptPublishLocation = ''
$config.Item("PSGallery").Trusted = $true
$config.Item("PSGallery").Registered = $true
$config.Item("PSGallery").InstallationPolicy = 'Trusted'
$config.Item("PSGallery").PackageManagementProvider = 'NuGet'
$config.Item("PSGallery").ProviderOptions = $config.Item("PSGallery").ProviderOptions

Export-Clixml -Path $xmlPath -InputObject $config

Thanks to Richard for his deep research on this issue …

Using Agent Ransack, I found that the repository data is stored in “c:\Users\\AppData\Local\Microsoft\Windows\PowerShell\PowerShellGet\PSRepositories.xml”

Richard Siddaway's Blog

In this post – – I stated that you could unregister the default PowerShell repository. I also said that the statement in the documentation for Unregister-PSrepository that you couldn’t unregister PSGallery was incorrect.

A couple of readers have left comments stating that they tried it and got an error message stating that PSGallery can’t be unregistered.

I did my first test on Windows 10 latest preview build – build 14926

PS> $PSVersionTable

Name Value
—- —–
PSVersion 5.1.14926.1000
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
BuildVersion 10.0.14926.1000
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3

I’ve just test on Windows Server 2016 TP5

PS C:Windowssystem32> $PSVersionTable

Name Value
—- —–
PSVersion 5.1.14300.1000
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
CLRVersion 4.0.30319.42000
BuildVersion 10.0.14300.1000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3

The version of PowerShell 5.1 on Server 2016 TP5 doesn’t have the –Default parameter on Register-PSrepositiry but this works


View original post 25 more words


Lightweight PowerShell Templating Engine




Simple templating engine to expand a given template text containing PowerShell expressions.


The text of the template to do the expansion


Path to template to do the expansion

.PARAMETER Desitination

Destination path to write expansion result.  If not specified, write to output stream.

.PARAMETER PsConfigurationPath                          

Path to file containing PowerShell code. This file could contain variable values to use when evaluating templates


Begin tag for detecting expand expression in template


End tag for detecting expand expression in template


$message=”hello”; .\Expand-Template.ps1 -Text ‘I would like to say [[$message]] to the world’





    [Parameter(Mandatory=$true, ParameterSetName=‘Text’,ValueFromPipeline=$true)]


    [Parameter(Mandatory=$true, ParameterSetName=‘Path’)]




    [string]$BeginTag = ‘[[‘,

    [string]$EndTag = ‘]]’


$BeginTag = [RegEx]::Escape($BeginTag)

$EndTag = [RegEx]::Escape($EndTag)

Write-Verbose ‘Expand-Template’

if ($Path) {

    if (!(Test-Path -Path $path)) { throw “Template-Expand: path `’$path`’ can’t be found”  }

    $Text = Get-Content -Path $path -Raw


if ($PsConfigurationPath) {

    if (!(Test-Path -Path $PsConfigurationPath)) { throw “Template-Expand: psConfigurationPath `’$psConfigurationPath`’ can’t be found” }

    Write-Verbose ” ** Loading PS Configuration file: $PsConfigurationPath

    . $PsConfigurationPath


$pattern = New-Object -Type System.Text.RegularExpressions.Regex `

                      -ArgumentList $BeginTag(.*?)$EndTag,([System.Text.RegularExpressions.RegexOptions]::Singleline)

$matchEvaluatorDelegate =  [System.Text.RegularExpressions.MatchEvaluator] {


           $expression = $match.get_Groups()[1].Value # content between markers

           Write-Verbose ”  ** expanding expression: $expression

           trap { Write-Error “Failed to expand template. Can’t evaluate expression ‘$expression‘. The following error occured: $_; break }

           Invoke-Expression -command $expression | Tee-Object -Variable result

           Write-Verbose ”  ** expanded expression evaluated value:`n$result`n”


$expandedText = $pattern.Replace($text, $matchEvaluatorDelegate)

if (-not $destination){ $expandedText }

else { Set-Content -Path $destination -value $expandedText -encoding $Encoding }

Restart Lenovo Laptop Audio

I have a Lenovo W540 Laptop at work.  Often times, when docking/undocking, the audio stops working or the audio will not play through the headphones or the On Screen Display stops working or the hotkeys don’t do the right thing.  Below is a batch script I assembled that will stop all affected services and re-start them.  It has worked so far, but let me know if you find a case where it does not work.


::Restart audio services and On Screen Display services
net stop AudioSrv
net stop AudioEndpointBuilder
net stop TPHKLOAD
net stop TPHKSVC
net start AudioEndpointBuilder
net start AudioSrv
net start TPHKLOAD
net start TPHKSVC
taskkill /F /FI "IMAGENAME eq Ravcpl*"

Fastest method to get MSMQ message counts

Getting MSMQ message counts can be painfully slow if there are large numbers of messages in a given queue. This PowerShell script is the fastes known way I have found to get the message counts of a queue. The time to get the counts is linear regardless of the number of messages.

Gets all queues' information from the specified computer

Gets all queues' information from the specified computer

Adapted from

Get-MessageQueueInfo.ps1 -MachineName rg-p-blu2 | sort -Property name| ft -Property Name,MessagesInQueue,BytesInQueue -AutoSize

param([string] $MachineName = $env:COMPUTERNAME)
$path = "\\{0}\root\CIMv2" -f $MachineName
$scope = new-object System.Management.ManagementScope ($path)
$QueryString = "SELECT * FROM Win32_PerfFormattedData_msmq_MSMQQueue"
$query = new-object System.Management.ObjectQuery ($queryString)
$searcher = new-object System.Management.ManagementObjectSearcher ($scope, $query)

Kill a process that is listening on a network port

Sometimes, you want to forcibly deploy/install a piece of software that requires a particular service port. This script will find any process that is listening on that port and kill it and if it is a windows service, also disable the service.

param([string]$Port = '80')

$a = netstat -a -n -o

$a -split [environment]::NewLine | foreach {
    $parts = $_.Split(" ", [System.StringSplitOptions]::RemoveEmptyEntries) 
    $isMatch = $parts | where {$_ -like "*:$Port*" }
    if($isMatch -and $parts[3] -like 'LISTENING') {
        $proc = Get-Process -Id $parts[4] -ErrorAction SilentlyContinue
        if(-not $proc) {continue}
        Write-Warning "A process was found listening on port $($parts[4])"
        $foundService = (Get-WmiObject Win32_Service -Filter "ProcessId='$($parts[4])'") 
        if($foundService) {
            Write-Host "The process was running as a service, the service will be stopped and disabled ($($foundService.PathName))"

        Write-Host "Killing process $($proc.Name)"
        kill -Id $parts[4] -Force
        $s = Get-Service

Parse output of handle.exe into objects for use with PowerShell

There are times when you need to determine the process that is locking a file.  Using the SysInternals “handle.exe” command line tool, we can search for processes that are using (i.e. locking) a particular file or directory. The code below translates the output of handle.exe into objects that are more friendly for use with PowerShell.

Add-Type -Language CSharp @"
public class Handle{
    public string ProcessName { get;set;}
    public int ProcessId {get;set;}
    public string Type {get;set;}
    public string User {get;set;}
    public string HandleId { get;set;}
    public string Name { get; set;}
    public string AppPoolName {get;set;}

function Get-HandlesAndProcessIds {
<# .Description Converts the text output of the SysInternals tool "handle.exe" into an object array .Example $handles = & handle.exe -a  -u -accepteula "MY_LOCKED_ASSEMBLY.dll" $allHandles = Get-HandlesAndProcessIds -HandleInfo $handles $allHandles --------------------------- ProcessName : dllhost.exe ProcessId   : 6960 Type        : File User        : DOMAIN\user HandleId    : B34 Name        : MY_LOCKED_ASSEMBLY.dll AppPoolName :  #>
    $handle = new-object Handle
    foreach ($line in $handles) {
        if($line -like "*pid:*") {
            $result = $line | Select-String –pattern '^([^ ]*)\s*pid: ([0-9]*)\s*type: ([^ ]*)\s*([^ ]*)\s*(.*?): (.*)'

            $handle.ProcessName =  $result.Matches[0].Groups[1].Value
            $handle.ProcessId = [int]::Parse( $result.Matches[0].Groups[2].Value)
            $handle.Type = $result.Matches[0].Groups[3].Value
            $handle.User = $result.Matches[0].Groups[4].Value
            $handle.HandleId =  $result.Matches[0].Groups[5].Value
            $handle.Name = $result.Matches[0].Groups[6].Value

            if($handle.ProcessName -like "w3wp.exe") {
                $process = Get-AppPoolProcesses | where { $_.ProcessId -eq $handle.ProcessId }
                if($process) {
                    $handle.AppPoolName = $Process.AppPoolName


function Get-AppPoolProcesses {
    Get-WmiObject -NameSpace 'root\WebAdministration' -class 'WorkerProcess' -ComputerName 'LocalHost' |
        select AppPoolName, ProcessId |
            sort -Property AppPoolName


Free Proverb Teleprompter software

I was recently tasked with coming up with a teleprompter solution for my church. One of the requirements was that the software could controlled with a remote control. None of the teleprompter software out there (free or commercial) was able to support custom key bindings. So I decided to create my own. It is pretty full featured, comparable to many of the commercially available ones. It requires the .NET 4.0 framework.

Download Proverb Teleprompter here