January 6th, 2009

Hey, Scripting Guy! How Can I Modify Registry Settings That Configure Windows Explorer?

Hey, Scripting Guy! Question

Hey, Scripting Guy! Why does it feel like every single default setting in Microsoft Windows is wrong? It is so frustrating to me to spend five minutes changing all the defaults. For example, I open Internet Explorer and there are no system files. I look at files, but there are no file extensions. The names of text files that I put in all capital letters so that they will be easy to find are not capitalized. And when the computer boots up, it takes forever because it is trying to find file shares and printers on the network. I mean it is easy enough to change; it is just time consuming, especially when I am troubleshooting an issue. Can you fix this please?

– WA

SpacerHey, Scripting Guy! Answer

Hi WA,

As someone who considers himself to be a power user, I most certainly sympathize with your complaint. However, as someone who has a mother who is not a power user and who lives more than 300 miles (482 kilometers) away, I am perfectly content with the defaults. So as much as I appreciate our readers, I will not file a user interface bug for you with the Windows team. What I will do, however, is show you the script I use to set things up the way I like them.

Standard disclaimer: The script today talks about editing the registry. Microsoft does not support editing the registry. If this script causes your computer to crash or you to gain weight, we warned you. If your cat begins to shed fur abnormally or your dog begins barking at the moon, well these things can happen if you are not careful. Changing the registry is not related to animal behavior or animal husbandry. Please back up your registry before proceeding to run this script. Back up your banking records from your computer. Send all your credit card information to the Scripting Guys, and we will hold all of it for you just in case of disaster.

Disclaimer about the standard disclaimer: Don’t send us any of your personal information. There’s a black hole down the hall from us.

The first thing you should do before working with the registry is make sure you are either working in a virtual machine that allows you to roll back changes if you wish, or ensure that you have a good backup of the registry. Jerry Honeycutt has written a number of good books about the registry for Microsoft Press, as well as a number of excellent articles such as this one.

For a good overview of the registry, you can refer to this article. To explore the registry, you can use the Tweakomatic, which produces scripts in VBScript. Here is a good Sesame Script article that provides an overview of the registry. And here is the Script Center registry archive.

In our script today we will modify several of the registry settings that configure Windows Explorer. Of course before we do that, we may want to see what the settings are. So we will create a script that contains two functions. One function displays the Windows Explorer settings, and the other will configure them. We first define some command-line parameters. To do this, we use the param keyword. Because these command-line parameters take effect only if they are present, we make them switched. This gives us the advantage of only retrieving the registry settings, only setting the registry settings, or getting the settings and then setting them as well. This image shows an example of obtaining only the registry settings for Windows Explorer:

Image that shows obtaining only the registry settings for Windows Explorer

 

The line of code that actually creates the parameter is shown here:

Param([switch]$get,[switch]$set)

We then create the Get-ExplorerSettings function. It is a scripting best practice to create the functions in the order in which they will be used in the script. If this is not possible, you may choose to arrange the functions alphabetically or by intended use. What you do not want is a jumble of functions whose only arrangement is the order in which you figured out you needed them. To create a function, we use the function key word. Because there is nothing to pass to the function, the parentheses are empty. This is seen here:

Function Get-ExplorerSettings()

After we have created the function definition, we create the script block for the Get-ExplorerSettings function. The script block begins and ends with curly brackets (which are like curly fries only with zero carbs). The cool thing about using Windows PowerShell to read the registry is that you can use the Get-ItemProperty cmdlet and specify the path parameter and—voila!— you get back all the properties from that registry key. This is seen here in a truncated fashion:

PS C:\> Get-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
PSPath                                : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Window
                                        s\CurrentVersion\Explorer\Advanced
PSParentPath                          : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Window
                                        s\CurrentVersion\Explorer
PSChildName                           : Advanced
PSDrive                               : HKCU
PSProvider                            : Microsoft.PowerShell.Core\Registry
Hidden                                : 1
ShowCompColor                         : 1
HideFileExt                           : 0
DontPrettyPath                        : 1
ShowInfoTip                           : 1

We use the Get-ItemProperty cmdlet to return the entire registry key. We store this custom Windows PowerShell object in a variable called $RegExplorer as seen here:

{
$RegExplorer =  Get-ItemProperty -Path HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced

It is time to print out the values we obtained from the registry. However, because we are not interested in everything from the registry key and we would like to explain a bit about the values, we use a subexpression and expanding strings to print out the information in which we are interested. There are two kinds of strings in Windows PowerShell. The first is expanding and the second is literal. The double quotation mark will expand the value of a variable. The problem here is that we want to avoid concatenation by using the expanding string. However, if we do not use a subexpression, we will get an unraveling of the object as seen here:

PS C:\> "Display hidden files and folders is $RegExplorer.SuperHidden"
Display hidden files and folders is @{Hidden=1; ShowCompColor=1; HideFileExt=0; DontPrettyPath=1; ShowInfoTip=1; HideIc
ons=0; MapNetDrvBtn=0; WebView=0; Filter=0; SuperHidden=1; SeparateProcess=0; ListviewAlphaSelect=0; ListviewShadow=0;
ListviewWatermark=0; TaskbarAnimations=0; StartMenuInit=2; StartButtonBalloonTip=2; ServerAdminUI=0; LoosenRudeAppCheck
=1; TaskbarSizeMove=0; TaskbarGlomming=1; Start_LargeMFUIcons=1; Start_MinMFU=6; Start_ShowControlPanel=1; Start_Enable
DragDrop=1; StartMenuFavorites=0; Start_ShowHelp=1; Start_ShowMyComputer=1; Start_ShowMyDocs=1; Start_ShowMyMusic=1; St
art_ShowMyPics=1; Start_ShowPrinters=1; Start_ShowRun=1; Start_ScrollPrograms=0; Start_ShowSearch=1; Start_ShowSetProgr
amAccessAndDefaults=1; Start_ShowRecentDocs=2; Start_AutoCascade=1; Start_NotifyNewApps=1; Start_AdminToolsRoot=2; Star
tMenuAdminTools=1; NoNetCrawling=1; FolderContentsInfoTip=1; FriendlyTree=0; WebViewBarricade=1; DisableThumbnailCache=
0; ShowSuperHidden=0; ClassicViewState=0; PersistBrowsers=0}.SuperHidden

As you can see, everything is displayed. To prevent this unraveling, we use the subexpression to force Windows PowerShell to evaluate what is in the parentheses first and then return the value to the string. We do this for all the property values in which we are interested, as shown here:

"Display hidden files and folders is $($RegExplorer.SuperHidden)"
"Hide File extensions is set to $($RegExplorer.HideFileExt)"
"Show system files and folders is set to $($RegExplorer.ShowSuperHidden)"
"Hide desktop icons $($RegExplorer.HideIcons)"
"Use Web view for folders $($RegExplorer.WebView)"
"Display correct file name capitalization $($RegExplorer.DontPrettyPath)"
"Prevent automatically locate file shares and printers $($RegExplorer.NoNetCrawling)"
} #end Get-ExplorerSettings

After creating Get-ExplorerSettings, it is time to create a function to allow us to change some of the values. The first thing we do is use the function keyword to create the Set-ExplorerSettings function as seen here:

Function Set-ExplorerSettings()

We could have cheaped out and used a series of Set-ItemProperty cmdlets, each with a hard-coded value for each property we wished to change. But then we decided that it would be much cooler to use a hash table here. Don’t get too excited about the term hash table—it is very similar to the Dictionary Object from VBScript fame.

To create a hash table, you use the ampersand and a set of curly brackets as seen here. Note that each key/value pair is assigned with an equal sign, and each pair is separated by the semicolon:

$a = @{"a" = 1; "b" = 2}

If you want to know how many items are in the hash table, you can use the count as seen here:

$a.Count

To walk through the hash table, you can use the foreach statement just like in VBScript. This is seen here:

foreach($key in $a.keys) { $key; $a[$key] }

Here you can see the hash table we create named $regValues:

{
 $RegValues = @{
                "SuperHidden" = 1 ;
                "HideFileExt" = 0 ;
                "ShowSuperHidden" = 0 ;
                "HideIcons" = 0 ;
                "WebView" = 0 ;
                "DontPrettyPath" = 1 ;
                "NoNetCrawling" = 1
                                    }

We can now create a variable to hold the path to the registry settings. We call the path variable $path (for obvious reasons):

$path = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"

When that is done, we need to walk through the hash table. To do this we use the foreach statement. We use the variable $key as the enumerator to keep track of our place in the collection of keys we obtain from the keys property. When we do this, we use the Set-ItemProperty cmdlet connect to the path specified in the $path variable, connect to the registry property name held in the $key variable, and assign the value that is associated with that element from the hash table. The last thing the function does is use an expanding string and a subexpression to print out a confirmation message for each registry key. This message is seen in this image:

Image of the confirmation message for each registry key

 

The complete foreach statement is shown here:

ForEach ($key in $RegValues.Keys)
  {
    Set-ItemProperty -path $path -name $key -value $RegValues[$key]
   "Setting $path $($key) to $($RegValues[$key])"
  }
} #end Set-ExplorerSettings

After that has been done, it is time to evaluate the command-line parameters to see which function gets called. To do this, we use the if statement. If the script was run with the –get parameter, the Get-ExplorerSettings function is called. If the script was run with the –set parameter, the Set-ExplorerSettings function is called. If both parameters are used, both functions will run. This is seen in this image:

Image that shows which functions are called

 

Here is the code that evaluates the command line:

if($get) { Get-ExplorerSettings }
if($set) { Set-ExplorerSettings }

The complete script is uploaded to the Scripting Guys Script Repository. You can download the script from that location … remember to save the file with a .ps1 file extension.

Well, WA, that is about it for today. Remember that you can use Tweakomatic to easily discover additional things you could configure by using this technique. See you tomorrow as we continue registry week.

Ed Wilson and Craig Liebendorfer, Scripting Guys

 

Author

0 comments

Discussion are closed.