Hey, Scripting Guy! Question

Hey Scripting Guy! Internet Explorer used to be limited to only downloading two items at a time. I found a script that would increase it to 10, but that script does not work on Windows 7. I got accustomed to being able to download 10 things at the same from within Internet Explorer. Do you have a script that will make that change for me?

-- TC

Hey, Scripting Guy! Answer

Hello TC,

Interestingly enough, Internet Explorer 8 has increased the number of concurrent downloads to 6. The reason your old script does not work on Windows 7 is because Internet Explorer 8 has new registry keys that store the configuration information. This would be the same situation on Windows Vista or Windows XP with Internet Explorer 8 installed on them. This information is documented in KB 282402. TC, as luck would have it, the 2009 Summer Scripting Games Beginner Event 5 had a task that involved modifying the registry key that controlled the number of concurrent downloads, so you have your pick of scripts that solve this problem.

This week we will be reviewing some of the scripts that were submitted during the recently held 2009 Summer Scripting Games. The description of the 2009 Summer Scripting Games details all of the events. Each of the events was answered by a globally recognized expert in the field. There were some cool prizes and winners were recognized from around the world. Additionally, just like at the "real Olympics," because there was a lot going on, an "if you get lost page" was created. Communication with participants was maintained via Twitter, Facebook, and a special forum. The special forum has been taken down, but we still use Twitter and Facebook to communicate with Hey, Scripting Guy! fans. We will be focusing on solutions that used Windows PowerShell. We have several good introduction to Windows PowerShell Hey, Scripting Guy! articles that you will find helpful.

For the 2009 Summer Scripting Games Event 5, you were tasked with reading and writing to the registry.  Bruno Leonardo submitted a nice script that uses the Windows PowerShell Registry provider to add the required values to the registry.

The first thing Bruno does is create a command-line parameter to allow you to specify the number of concurrent connections when you run the script. This is seen here.

param($connections=10)

When you run the script, if you supply a number on the command line, that number will be used for the maximum number of connections. If you do not supply a number, the value of the $connections variable defaults to 10. There are several ways the script could be called. These are seen here:

ScriptingGamesBeginnerEvent5.ps1 9
ScriptingGamesBeginnerEvent5.ps1 –connections 9
ScriptingGamesBeginnerEvent5.ps1 –c 9

One improvement to the script would be a check to ensure that valid command-line input is received. This would include checking that the input is an integer and that the number falls inside an allowed range of something like 1-20. In Windows PowerShell 2.0, this is easy to do by using parameter validation parameters. But the same thing can be accomplished in Windows PowerShell 1.0 by writing your own function. An example of this is seen in the Test-AllowedValue function:

Function Test-Allowedvalue([int]$connections)
{
 if($connections -ge 1 -AND $connections -le 20)
   { $true }
 else { $false }
} #end function Test-Allowedvalue

To call the Test-AllowedValue function, you pass your value to the function and evaluate the return value. The Test-AllowedValue function returns a Boolean true/false depending on the result of the evaluation. This is seen here:

$connections = 5
if(Test-AllowedValue -connections $connections)
  { "it worked" }
else { "$connections is not an allowed value" }

After creating the command-line parameters, Bruno creates two variables that hold the registry keys that need to be modified. Due to publishing constraints, I had to modify the lines so that they would fit on two lines. To do this, I used the + sign as seen here:

$PATH_KEY = 'hklm:\SOFTWARE\Microsoft\Internet Explorer\MAIN' +
  '\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER'
$PATH_KEY_1_0 = 'hklm:\SOFTWARE\Microsoft\Internet Explorer\MAIN' +
  '\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER'

The Get-ItemProperty cmdlet is used to read the two registry keys and the results are stored in variables. This is seen here:

$current_key = (Get-ItemProperty $PATH_KEY).'iexplorer.exe'
$current_key_1_0 = (Get-ItemProperty $PATH_KEY_1_0).'iexplorer.exe'

If the registry key values are null, it means that the registry keys will need to be created. The if statement is used to determine if the registry key values are present. If they are not present, the New-ItemProperty cmdlet is used to create the registry key values and to set them to the number stored in the $connections variable. This is seen here:

if ($current_key -eq $null -or $current_key_1_0 -eq $null) {
  Write-Host -foreground green "Value not currently set, creating new Key with value = $connections."
  New-ItemProperty $PATH_KEY -Name 'iexplorer.exe' -Value $connections
  New-ItemProperty $PATH_KEY_1_0 -Name 'iexplorer.exe' -Value $connections
}

When the script is run, the following output is seen from creating the registry keys:

Value not currently set, creating new Key with value = 10.


PSPath        : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER
PSParentPath  : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl
PSChildName   : FEATURE_MAXCONNECTIONSPERSERVER
PSDrive       : HKLM
PSProvider    : Microsoft.PowerShell.Core\Registry
iexplorer.exe : 10

PSPath        : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER
PSParentPath  : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\FeatureControl
PSChildName   : FEATURE_MAXCONNECTIONSPER1_0SERVER
PSDrive       : HKLM
PSProvider    : Microsoft.PowerShell.Core\Registry
iexplorer.exe : 10

If the registry keys are present, it means they have been previously set by script because by default the registry keys are not seen in the registry. The current values that are stored in the registry are displayed and then the number stored in the $connections variable is written to the registry by using the Set-ItemProperty cmdlet. This is seen here:

else {

 
Write-Host -foreground green `
"
Current values for iexplorer.exe key:
${PATH_KEY}: $current_key
${PATH_KEY_1_0}: $current_key_1_0

Setting value to $connections.
"
  Set-ItemProperty $PATH_KEY -Name 'iexplorer.exe' -Value $connections
  Set-ItemProperty $PATH_KEY_1_0 -Name 'iexplorer.exe' -Value $connections
}

The complete ScriptingGamesBeginnerEvent5.ps1 script is seen here.

 

ScriptingGamesBeginnerEvent5.ps1

param($connections=10)
$PATH_KEY = 'hklm:\SOFTWARE\Microsoft\Internet Explorer\MAIN' +
  '\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER'
$PATH_KEY_1_0 = 'hklm:\SOFTWARE\Microsoft\Internet Explorer\MAIN' +
  '\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER'
$current_key = (Get-ItemProperty $PATH_KEY).'iexplorer.exe'
$current_key_1_0 = (Get-ItemProperty $PATH_KEY_1_0).'iexplorer.exe'

if ($current_key -eq $null -or $current_key_1_0 -eq $null) {
  Write-Host -foreground green "Value not currently set, creating new Key with value = $connections."
  New-ItemProperty $PATH_KEY -Name 'iexplorer.exe' -Value $connections
  New-ItemProperty $PATH_KEY_1_0 -Name 'iexplorer.exe' -Value $connections
} else {

 
Write-Host -foreground green `
"
Current values for iexplorer.exe key:
${PATH_KEY}: $current_key
${PATH_KEY_1_0}: $current_key_1_0

Setting value to $connections.
"
  Set-ItemProperty $PATH_KEY -Name 'iexplorer.exe' -Value $connections
  Set-ItemProperty $PATH_KEY_1_0 -Name 'iexplorer.exe' -Value $connections
}

When you run the script, you are presented with this output if the registry values are already present:

Image of script output if registry values already present

Because the ScriptingGamesBeginnerEvent5.ps1 requires administrative access to work with the HKEY_LOCAL_MACHINE registry hive, you may want to modify the script so that it does not display an error when it is run as a normal user. The easy way to do this is to set the error action preference automatic variable to SilentlyContinue and clear the errors on the $error variable. This is seen here:

$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

When you call the New-ItemProperty cmdlet or the Set-ItemProperty cmdlet, check the value of the $error.count property. If the $error.count is greater than 0, an error occurred during the operation. The most recent error is stored in element 0 of the $error array. This is seen here:

if($error.Count -ne 0)
    { "This script requires admin rights." ; $error[0] ; exit }

One additional modification to the script that will improve the efficiency of it is to examine the value stored in the registry key. If the value is the same as the value supplied for the $connections variable, there is no reason to set it again. Therefore, a message is displayed that indicates the registry does not need to be updated. This is seen here:

if($connections -eq $current_key)
    {"connection value does not need updating" ; exit }

The complete ScriptingGamesBeginnerEvent5_Modified.ps1 script is seen here.

ScriptingGamesBeginnerEvent5_Modified.ps1

param($connections=10)
$ErrorActionPreference = "SilentlyContinue"
$error.Clear()

$PATH_KEY = 'hklm:\SOFTWARE\Microsoft\Internet Explorer\MAIN' +
  '\FeatureControl\FEATURE_MAXCONNECTIONSPERSERVER'
$PATH_KEY_1_0 = 'hklm:\SOFTWARE\Microsoft\Internet Explorer\MAIN' +
  '\FeatureControl\FEATURE_MAXCONNECTIONSPER1_0SERVER'
$current_key = (Get-ItemProperty $PATH_KEY).'iexplorer.exe'
$current_key_1_0 = (Get-ItemProperty $PATH_KEY_1_0).'iexplorer.exe'

if ($current_key -eq $null -or $current_key_1_0 -eq $null)
 {
  Write-Host -foreground green "Value not currently set, creating new Key with value = $connections."
  New-ItemProperty $PATH_KEY -Name 'iexplorer.exe' -Value $connections | Out-Null
  New-ItemProperty $PATH_KEY_1_0 -Name 'iexplorer.exe' -Value $connections | Out-Null
  if($error.Count -ne 0)
    { "This script requires admin rights." ; $error[0] ; exit }
  else { "Registry keys successfully created" }
 } #end if registry key not present
else
 {
  Write-Host -foreground green "Current value HTTP 1.0 $current_key_1_0"
  Write-Host -foreground green "Current value for greater than HTTP 1.0 $current_key"

  if($connections -eq $current_key)
    {"connection value does not need updating" ; exit }
  else
    {
     Set-ItemProperty $PATH_KEY -Name 'iexplorer.exe' -Value $connections
     Set-ItemProperty $PATH_KEY_1_0 -Name 'iexplorer.exe' -Value $connections
     if($error.Count -ne 0)
       { "This script requires admin rights." ; $error[0] ; exit }
     else { "Registry value successfully modified" }
    } #end else connection key update
 } #end else registry key present

Bruno, we thank you for contributing a cool Windows PowerShell script to the 2009 Summer Scripting Games. TC, we hope you have enjoyed this response to your question about changing the Internet Explorer download values.

If you want to be the first to know what is happening on the Script Center, follow us on Twitter or Facebook. If you need assistance with a script, you can post questions to the Official Scripting Guys Forum or send an e-mail to scripter@microsoft.com. Join us again Monday for another fun-filled weeking of scripting. Until then, peace.

Ed Wilson and Craig Liebendorfer, Scripting Guys