Nigel Boulton's Blog
5Dec/104

Checking File Associations with the help of PowerShell Remoting

I recently needed to check the file association for .JPG files across a whole Citrix server estate, as we’d received reports of files of these types not always opening as expected. Because PowerShell remoting is enabled on every server, this was a very easy job..!

The code snippet below is what I used. A script block is run remotely on each server using the Invoke-Command cmdlet. The script block then uses the Get-ItemProperty cmdlet to read the registry to get the default file association for .JPG files (via the “jpegfile” class) and reports OK if it is as expected, or the actual value that is set if not:

1..176 | ForEach-Object {
	$ServerName = "SERVER$_"
	Write-Host "$($ServerName): " -NoNewLine
	Invoke-Command -ComputerName $ServerName -ScriptBlock {
		$Value = Get-ItemProperty "Registry::HKEY_CLASSES_ROOT\jpegfile\shell\open\command" "(Default)" | Select-Object -ExpandProperty "(Default)"
		if ($Value -eq "C:\Windows\System32\rundll32.exe `"C:\Program Files\Windows Photo Gallery\PhotoViewer.dll`", ImageView_Fullscreen %1") {
			Write-Host "OK"
		} else {
			Write-Host $Value
		}
	}
}

Update: Please see the comment below from Jeffrey Snover. Jeffrey's approach makes use of the concurrency feature of Invoke-Command, which executes the command on 32 servers simultaneously (by default) and so returns the results substantially faster.

In my opinion, PowerShell remoting is by far the best version 2.0 feature. If you don’t already have it enabled across your server estate I’d strongly recommend doing so as it can save hours of effort.

Depending on your environment, there may be a few hoops you have to jump through to get remoting working properly, but it will be time well spent.  PowerShell MVP Jonathan Medd has an excellent post on his blog on Enabling PowerShell 2.0 Remoting in an Enterprise and Ravikanth Chaganti has produced a helpful multi-part PowerShell 2.0 remoting guide.

Be aware though that unfortunately there are some things that can’t be run remotely – a month or two ago I was doing some work with WSUS and discovered that it’s not possible to call the IUpdateSession::CreateUpdateDownloader method remotely for example. Shame!

Comments (4) Trackbacks (1)
  1. Try it this way, I think you’ll like it. The difference is that this will work against 32 servers simultaneously vs 1 at a time so it should finish much quicker.

    #####################################
    $Servers = $(1..176 | foreach {"SERVERS$_"})
    
    Invoke-Command -ComputerName $Servers -ScriptBlock { 
        $Value = Get-ItemProperty "Registry::HKEY_CLASSES_ROOT\jpegfile\shell\open\command" "(Default)" | 
        Select-Object -ExpandProperty "(Default)"
        if ($Value -eq "C:\Windows\System32\rundll32.exe `"C:\Program Files\Windows Photo Gallery\PhotoViewer.dll`", ImageView_Fullscreen %1") { 
            New-Object psobject -Property @{ Host = hostname; Value = "OK"}
        } 
        else { 
            New-Object psobject -Property @{ Host = hostname; Value = $Value}
        } 
    } 
    ############################################

    Returning a PSObject allows you to manipulate it when you get back (e.g. filtering or grouping).

    You might want to experiment with -Throttlelimit which determines how many machines it will work with at one time:

    Invoke-Command -ComputerName $Servers -throttlelimit 200 -ScriptBlock { 

    I would love to hear how this works for you.

    Enjoy!

    Jeffrey Snover [MSFT]
    Distinguished Engineer
    Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
    Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

    • Many thanks for your comment Jeffrey, it was much appreciated.

      You wanted to hear how your approach worked for me – well, I did some tests today and it’s nine times faster than mine! And that was just with the default Throttlelimit – I haven’t had chance to try tweaking that yet.

      Wow – just when I think PowerShell is just about as cool as it can be, you come along and show me something that makes it nine times cooler! Thank you!

  2. Is there a way with PowerShell to “give a program all it’s defaults”? In other words, say I want Windows Photo Viewer to be the default handler for all file types it is capable of handling. This can be done in the Default Programs control panel, but I want to do it programmatically.

    • Not as far as I know Shawn. I think you would need to write a script to do this, as file associations are stored by file type (not application) in the registry. I assume that the Default Programs applet has an internal record of which extensions can be handled by a given application.


Leave a comment