How to scope/limit the effect of Enter-VsDevShell? - visual-studio

I am scripting the build of a third-party piece of software, which also is the reason why I need to accommodate its needs. The third-party software expects nmake to be available along with compiler, linker, librarian and other tools found in the MSVC toolchain.
So I thought I'd use Enter-VsDevShell from Microsoft.VisualStudio.DevShell and be done with it. Here's my minimal script to show the issue:
Set-StrictMode -Version Latest
function Get-VSBasePath
{
Param($vsrange = "[16.0,18.0)")
$vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
$vspath = & $vswhere -products "*" -format value -property installationPath -latest -version "$vsrange"
return $vspath
}
function Do-Stuff
{
Param($arch = "x64")
$vspath = Get-VSBasePath
if (-not (Get-Command Enter-VsDevShell -CommandType Cmdlet -ErrorAction silentlycontinue))
{
Import-Module "$vspath\Common7\Tools\Microsoft.VisualStudio.DevShell.dll" -Force|Out-Host
}
Enter-VsDevShell -VsInstallPath "$vspath" -DevCmdArguments "-arch=$arch -no_logo" -SkipAutomaticLocation|Out-Host
}
echo "Do we know cl.exe now? (#1)"
Get-Command cl -CommandType Application -ErrorAction silentlycontinue|Out-Host
echo "Calling Do-Stuff"
Do-Stuff
echo "Do we know cl.exe now? (#2)"
Get-Command cl -CommandType Application -ErrorAction silentlycontinue|Out-Host
After the Import-Module I can see there is no counterpart cmdlet to Enter-VsDevShell in that module:
$ Get-Command -Module Microsoft.VisualStudio.DevShell
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Enter-VsDevShell 17.0.0.0 Microsoft.VisualStudio.DevShell
Cmdlet Send-VsDevShellTelemetry 17.0.0.0 Microsoft.VisualStudio.DevShell
Issuing a Remove-Module Microsoft.VisualStudio.DevShell also doesn't undo the effect of Enter-VsDevShell, unfortunately. My guess is that for the most part it affects environment variables. It even leaks its effect into the calling PowerShell.
So how can I limit the effect of Enter-VsDevShell to only the Do-Stuff function, say?
I need to run several builds back to back in order to build for all my desired target platforms. And that's why I want to limit the effect of Enter-VsDevShell.
I have also tried issuing another Enter-VsDevShell with a different target platform, but it doesn't work reliably.

Related

How to get Paths to all executables from Get-ChildItem

I am currently trying to get a list of all installed applications and would like to build a feature that can launch those.
I'm using these PowerShell commands:
gci HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | % { Get-ItemProperty $_.PsPath } | Select DisplayName,InstallLocation
gci HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | % { Get-ItemProperty $_.PsPath } | Select DisplayName,InstallLocation
in conjunction with ConvertTo-Json in order to get a good stdout I can work with.
Now, this only gives me the InstallPath without any executables.
Is there any easy way to get the main executable of the applications i nthe list?
Expected Result (Name of the key does not matter):
// ...
{
"DisplayName": "Microsoft Edge",
"InstallLocation": "C:\\Program Files (x86)\\Microsoft\\Edge\\Application",
"LaunchApplication": "C:\\Program Files (x86)\\Microsoft\\Edge\\Application\msedge.exe",
},
{
"DisplayName": "Audacity 2.4.2",
"InstallLocation": "C:\\Program Files (x86)\\Audacity\\",
"LaunchApplication": "C:\\Program Files (x86)\\Audacity\\audacity.exe"
},
// ...
Like others have pointed out in the comments, there isn't a conventional way of getting the executable paths of certain programs.
To answer your indirect question of building an app launch method, we can make use of a few things. Fortunately for us, PowerShell has a Get-StartApps cmdlet that produces an output of the current users installed apps:
Name AppID
---- -----
3D Viewer Microsoft.Microsoft3DViewer_8wekyb3d8bbwe!Microsoft.Microsoft3DViewer
AdGuard AdGuard
Adobe Acrobat DC {6D809377-6AF0-444B-8957-A3773F02200E}\Adobe\Acrobat DC\Acrobat\Acrobat.exe
Battle.net {7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}\Battle.net\Battle.net Launcher.exe
Blend for Visual Studio 2022 Blend.d58ce8bb
Calculator Microsoft.WindowsCalculator_8wekyb3d8bbwe!App
Calendar microsoft.windowscommunicationsapps_8wekyb3d8bbwe!microsoft.windowslive.calendar
There are 2 properties that are displayed:
Name
AppID.
This becomes important due to the AppID being the value needed for shell: to execute/launch the program. Given the above output of Get-StartApps, you can launch "Adobe Acrobat DC" by passing the AppID to shell:\AppsFolder\"AppID".
Start-Process shell:AppsFolder\"{6D809377-6AF0-444B-8957-A3773F02200E}\Adobe\Acrobat DC\Acrobat\Acrobat.exe"
Using #zett42's approach, we can query your start menu, along with the system start menu folder paths for .lnk's retrieving its target path using the WScript COM object:
$paths = "C:\ProgramData\Microsoft\Windows\Start Menu\Programs","$env:APPDATA\Microsoft\Windows\Start Menu"
Get-ChildItem -Path $paths -Filter "*.lnk" -File -Recurse |
ForEach-Object -Begin {
$WScriptShell = New-Object -ComObject "WScript.Shell"
} -Process {
[PSCustomObject]#{
Name = $_.BaseName
Path = $WScriptShell.CreateShortcut($_.FullName).TargetPath
}
} -End {
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($WScriptShell) #release COM object
}
which will output:
Name Path
---- ----
Adobe Acrobat DC C:\Program Files\Adobe\Acrobat DC\Acrobat\Acrobat.exe
Blend for Visual Studio 2022 C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\Blend.exe
Firefox C:\Program Files\Mozilla Firefox\firefox.exe
Google Chrome C:\Program Files\Google\Chrome\Application\chrome.exe
Microsoft Edge C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe
TechPowerUp GPU-Z C:\Program Files (x86)\GPU-Z\GPU-Z.exe
Not entirely sure this is what you're after, but it may be of help to others.

How to get list of "view installed updates" in "programs and features" in control panel using Powershell?

Trying to get all installed updates (including updates of third party apps like Acrobat etc.) which can be seen by clicking "view installed updates" in "programs and features" in control panel.
Below methods didn't help, probably because they are limited to Microsoft/Windows only:
New-Object -ComObject Microsoft.Update.Session
Get-WmiObject Win32_QuickfixEngineering
Example: I want to get KB2565063 from attached image below
Thanks
I found the following options:
$x = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.DisplayName -like "*foo*" }
$y = Get-ItemProperty HKLM:\SOFTWARE\Classes\Installer\Dependencies\* | Where-Object {$_.DisplayName -like "*foo*" }
In $x you have the software from "Uninstall a program" and in $y you have the update from "Installed Updates".
I'm not very happy with it, I'd like to know how windows actually link $x and $y together without searching simply for the name.
Maybe someone can fix the missing part for us :-)
EDIT
I found the solution:
Get-ItemProperty HKLM:\Software\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-Object { $_.ParentDisplayName -like "*foo*" }
This returns an object where ParentDisplayName is your program and DisplayVersion is the update version.
I'm assuming you want packages with the msu provider:
get-package -ProviderName msu
Name Version Source ProviderName
---- ------- ------ ------------
Update for Microsoft Defend... msu
Security Intelligence Updat... msu
Security Intelligence Updat... msu

Check if program with specific version is installed

I'm trying to create a very simple script which would check if the a specific program is installed and if so return the version number for that program.
I've been able to get to the point where I'm running the script and able to return a binary value if a program is installed or not but not sure how to return the version number for that installed program.
What I will post will be just what I'm doing to return if program is installed, and need help in then attaining the version number.
function Check_Program_Installed {
$my_check = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* |
Select-Object DisplayName, DisplayVersion, InstallDate |
Format-Table -AutoSize |
Out-String
# Check if Google Chrome is installed
$my_check -Match "Google Chrome"
}
Check_Program_Installed
If you want that function to look for a specific installed program instead of returning a (table) formatted string, then you could simply do:
function Check_Program_Installed {
[CmdletBinding()]
Param(
[Parameter(Position = 0, Mandatory=$true, ValueFromPipeline = $true)]
$Name
)
$app = Get-ItemProperty -Path "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*" |
Where-Object { $_.DisplayName -match $Name } |
Select-Object DisplayName, DisplayVersion, InstallDate, Version
if ($app) {
return $app.DisplayVersion
}
}
Check_Program_Installed "Google Chrome"
This will return $null when not found, or the version as string like 70.0.3538.67
Instead of doing the match after formatting the table, you could add a where to select the result you need beforehand and then obtain the DisplayVersion directly from that object. You could clean this up more to do exactly what you need, but here is your code modified to retrieve and display the number if the application is found. Try switching to a bad name to see the else result:
function Get-ApplicationVersion {
$applicationName = "Google Chrome"
$my_check = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, InstallDate | Where -Property DisplayName -Match $applicationName
$versionNumber = $my_check.DisplayVersion
if ($my_check) {
$versionNumber
}
else {
write-warning "Application not found"
}
}
Get-ApplicationVersion
EDITED: Renamed function name from Check_Program_Installed to use PS common verb Get, per suggestion.
function Get-InstalledProgram {
Param (
$ProgramName
)
$UninstallKeys = Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
if ( $ProgramName )
{
$UninstallKeys | Where-Object -Property DisplayName -Match -Value $ProgramName | Select-Object DisplayName, DisplayVersion, InstallDate
}
else
{
$UninstallKeys | Select-Object DisplayName, DisplayVersion, InstallDate
}
}
If you wanted to see all the programs, then you don't have to add a parameter. Just pipe its output to Format-Table. Format-Table does some weird just where the items are no longer the objects you're expecting, but table objects. Here is how I would handle that:
Get-InstalledProgram | Format-Table -Autosize
If you want to search for a program, add a parameter. You'll see above I added a parameter for ProgramName. It will match this term to the registry key's DisplayName.
PS C:\> Get-InstalledProgram -ProgramName Java
DisplayName DisplayVersion InstallDate
----------- -------------- -----------
Java 8 Update 181 8.0.1810.25 20180725
Java Auto Updater 2.8.181.13 20180925
If you wanted to just get the version, I would recommend just piping your output to Select-Object -ExpandProperty DisplayVersion
PS C:\> Get-InstalledProgram -ProgramName 'Java 8' | Select-Object -ExpandProperty DisplayVersion
8.0.1810.25
tl;dr
In Windows PowerShell[1] v5.1+, use the following (searches among both 32-bit and 64-bit installed programs, as shown in Control Panel):
Get-Package -ProviderName Programs -IncludeWindowsInstaller '*Google Chrome*' |
ForEach-Object Version
Note: The 32-bit-only HKEY_LOCAL_MACHINE:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall registry key may have more specific entries than what Control Panel shows - I'm unclear on why, but perhaps the composite view in Control Panel is sufficient.
Applied to your example:
PS> (Get-Package -ProviderName Programs -IncludeWindowsInstaller '*Google Chrome*').Version
70.0.3538.67
As for what you tried:
Since you're checking the Wow6432Node registry key branch specifically, you're checking installed 32-bit programs only.
As such, a better name for your function would be Check_32BitProgram_Installed or, more in line with with the function's intent, using an approved PowerShell verb, Get-32BitProgramVersion.
Alternatively, name, the function Get-ProgramVersion and look in both the 32-bit and 64-bit locations and process the results as shown in Theo's and Kevin M. Lapio's and Shawn Esterman's helpful answers:
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*,
HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*
In line with the generic title of your question, the above is a solution that essentially searches the list of installed applications you would see in Control Panel > Programs > Programs and Features (appwiz.cpl), which covers both 32-bit and 64-bit applications:
Windows PowerShell v5.1 comes with the PackageManagement module and a Programs package provider[1] that allows inspecting installed programs via the Get-Package cmdlet; in PSv3 and PSv4, it is possible to manually install it.
To list installed programs (shown with abridged sample output):
PS> Get-Package -ProviderName Programs -IncludeWindowsInstaller
Name Version Source ProviderName
---- ------- ------ ------------
Git version 2.18.0 2.18.0 Programs
Microsoft Azure Compute Emu... 2.9.8699.20 Programs
Microsoft Azure Authoring T... 2.9.8699.20 Programs
# ...
The output objects are of type [Microsoft.PackageManagement.Packaging.SoftwareIdentity], which have .Name and .Version properties, which enables the solutions above.
The Programs package provider supports two dynamic options (options specific to that provider):
-IncludeWindowsInstaller is needed to make the list of programs reported match what Control Panel shows.
-IncludeSystemComponent, by contrast, reports components that do not show in Control Panel.
[1] Unfortunately, the underlying Programs package provider is not available in PowerShell Core on Windows as of v7.0 - and I'm unclear on whether that is a not-yet situation or whether it will never be - see GitHub issue #13225.

I want to install VB6 on windows 10 OS. I need to work on VBP project so I have to install VB6 seamlessly

I have VB6 enterprise version set up but it is not able to complete its installation.(Hang)
I have tried installer from following link: http://nuke.vbcorner.net/Tools/VisualStudio6Installer/tabid/93/language/it-IT/Default.aspx
The condition for above installation you need to have msdn image files ready which I don't have. How can I get VB6 installed on Windows 10?
I followed the instructions here to create VB 6 and VB6 SP6 installers for Windows 10.
Simple and fast to create, and worked without issue.
This should work for you, but make sure you read through all the comments as the zero-byte file seems to have stopped working on later builds so there are some workarounds others shared. Though honestly, if all it is doing is stopping a reboot, I don't see why that matters. Copied main text here in case link dies some day.
Stop the Reboot
As in my previous tutorials for installing VB6 on Windows 7 and Windows 8, you'll want to create a zero byte file called MSJAVA.DLL. Creating this file in C:\Windows will prevent the need for a reboot at the end of the installation. If you're not familiar with how to create a zero-byte file, just click that link back there.
Let's Get Started
The first thing that you'll notice after inserting your installation media is the Program Compatibility Assistant popping up with a warning of known compatibility issues. Close it - we need to run setup manually. If you have autorun turned off, you'll get this pop up when you run setup.
Navigate to the installation media, and find the setup program. Right click setup.exe, and select Run As Administrator. Very important! Setup needs to do some registry twiddling and register some items with Windows, and won't be able to do it without the necessary permissions.
Simply click the option that reads Run the program without getting help, and the main setup wizard will start.
The first few screens are the usual stuff, things you've seen before:
Welcome Screen - Gives you the opportunity to vew the readme. Just
click Next unless your really want to read it!
EULA - Yep, it's the End User License Agreement. Scroll it, then
signal your acceptance in the appropriate radio button, then click
Next.
Product Number and USer ID - This is where you put in your user name,
company name and product ID. Fill in the fields as you see fit, and
click Next to continue with the wizard.
What to install - Two options here; VB6 Enterprise Edition, or Server
Applications. I am going with the first option
Common Installation folder - I accepted the default for this:
C:\Program Files (x86)\Microsoft Visual Studio\Common
Welcome and Warning - Copyright protection, inability to update files
in use, etc. Click Continue to move on
Visual Basic 6.0 Enterprise Setup - This is where the actual
installation of VB6 begins. Your PID is shown on the screen, and you
are invited to write it down if you have not already. Click Ok to
continue
Main Installation
On the first screen of the ACM Setup, leave the installation folder at the default, and click the Custom option for setup. The next screen will be the options list.
I don't use SourceSafe, so I cleared the checkbox. If you use SourceSafe, then by all means leave it checked for installation.
Very important (editor's note: see comment at the end) - Clear the checkbox for Data Access. If you don't, set up will hang at the end of the installation. Not sure for the real reason, but the theory is that setup is trying to register with Windows on a non-existent service. Clearing the Data Access checkbox stops this registration attempt.
Click Continue to carry on with the installation process. At this point, if you didn't create the empty MSJAVA.DLL file in C:\Windows, you'll get a restart Windows prompt. Go ahead and restart if you need to, I'll wait.
In any event, you'll get an MSDN installation wizard. I decline this, since much more information is available online anyway.
Now you'll get an option Server Setups dialog. If you want to install BackOffice, Visual SourceSafe Server, or SNA server, you have the opportunity at this point. I don't use these items, so I just click Next to blow by it.
Finally, we get to the last screen of the wizard. Un-check the Register Now checkbox, and click Finish.
Getting VB6 Running for the First Time
You can find the new shortcuts in your start menu, under the usual Microsoft Visual Basic 6.0 program group. You might be tempted to just fire it up straight away, and you can. But, you'll receive a nasty error about Automation, Error accessing the registry. You can blow by the error, but you'll just keep getting it every time you fire up VB6, and some data-access related items won't work correctly.
So, to get past this behavior, right-click the Microsoft Visual Basic 6.0 program icon in the start menu group, and select Run As Administrator. Click Yes in the resulting UAC dialog, and VB6 will start normally, presenting the new project wizard.
Ok, the first post-setup task is complete. Now on to the final piece.
Fixing the IDE Chug
Now before you start building a new project or editing an existing one, there is one more bit of configuration you might need to do. In running the IDE in a Windows 10 virtual machine, I've found that the IDE is somewhat sluggish when sizing and/or placing controls on a form, as well as sizing the form itself. This problem also presented itself in Windows 7 and Windows 8. We need to configure a couple things about the run properties of the IDE to fix this.
Be sure the IDE is closed, then right-click the start menu icon again. This time select Open file location.
In the explorer window that appears, right click the Microsoft Visual Basic 6.0 icon, and select properties. In the Properties window, select the Compatibility tab. On the Compatibility tab, click the Change settings for all users button.
In the new VB6 Properties window, place a tick mark in the Run this program in compatibility mode for: checkbox, and select Windows XP (Service Pack 3) from the drop down.
Under Settings, check the Reduced color mode checkbox, and change the dropdown to 16-bit (65536) color.
Put a check mark in the Disable display scaling on high DPI settings.
Click Ok, then Ok again.
Install with Data Access (from last comment as of 7/3/16)
I was succesfully able to install Visual Studio 6 Professional on
windows 10 Pro 64bit WITH Data Access. It is very simple, just
install VS6 as you normally would with Data Access enabled, it will
freeze when you try to finalize the install. Allow it to freeze, then
end the installation task. You will still have all the install files
and will be able to run the program. Now, you will need to install
the VB6 service pack 6, but it won't allow you to since visual studio
did not install correctly. To fix this, install VS6 over again, this
time uncheck data access components, install as normal. Afterward,
run the service pack and you should be good to go.
Update to my above post about the Help facility. Even though I installed the MSDN Library using the CDs and copied an old winhlp32.exe from an XP machine, that allowed me to view ".HLP" files from Win10, but from within VB6 no help worked. Finally, I was able to go to this website and download vshelp.exe.
http://download.cnet.com/Visual-Studio-Help-Engine-for-MSDN-Enables-MSDN-menu-functionality-in-Visual-FoxPro/3000-2213_4-10727794.html
It ran in a flash and made all the Visual Studio / Visual Basic 6.0 Help work including context sensitive help.
The VB6 installer wizard Visual Studio 6.0 Installer wizard to install the VB6 programming IDE and the MSDN library has been downloaded over 175,000 times.
You need to have your VB6 or VS6 CD and your VB6 serial number.
It works on Windows 7, 8.x, or 10 32bit or 64bit.
I got VS6/VB6 Running under Windows 10 by following the many posts on the Internet involving 1) lowering UAC + REGEDIT check, 2) copy a real MSJAVA.DLL from the VS Install Disk 1 IE4 Folder (un-7-Zip MSJAVX86.EXE) dragging MSJAVA.DLL to all the Windows SYSTEM32/SYSWOW64 folders (a zero byte MSJAVA.DLL no longer works), 3) placing and REGSVR32'ing dx7vb.dll (in the same folders as prior step), then using MSCONFIG to boot Win10 in Safe mode, and running the install from the original MSDN CDs. [No CDs? Read on]
For VB6 you only need DISC 1, both MSDN CDs, and the Service Pack 6 (get it on the Internet). WARNING: The install for DISC 1 will become "Not Responding". In my case, after an hour, I figured it must be done, so let Win10 close it as a "not responding window", and it went on with the MSDN and it worked. (you can also install MSDN standalone from the CDs later) If you can't get the SP6 update to work try by putting it on a Thumbdrive in the root and call the Volume name VS6SP6. In fact, for VB6 if you don't have the CDs anymore, you can create CDs with the contents of each install folder provided you give the CD Volume Label names as follows:
VB6 Disc 1 Volume Label: VSP600ENU1
VB6 Disc 3 Volume Label: DN600ENU1
VB6 Disc 4 Volume Label: DN600ENU2
When done, restore MSCONFIG to normal boot then raise your UAC back up.
One Glitch, I've not yet fixed. ".HLP" files are not supported under Windows 10, so no VB6 Help will be available (that's MSDN). However, I've read (but not tried) that I can copy WINHLP32.EXE from an XP machine to Win10 Windows dir. But first I've gotta get my old XP machine running.
For now, I'm re-developing all my VB programs (without the HELP facility) under Windows 10 Home Edition just fine and merrily doing my compiles again!
Hope this helps.
I made this script a while ago because I was having trouble with the installers and fixes I found around the internet. It incorporates all the tricks and tips that I found around the internet into one powershell script.
To run the script you will need to following:
VB6 Installer
Service Pack 6
Mouse Wheel Fix (Optional, set -SkipMouseWheel switch to skip.)
Each of the above should be placed in its own folder. If you save (and then dot-source) the script in a folder that contains these three folders it'll auto-detect everything for you. You can also set your current location in powershell to this folder and copy the script directly to you session and it'll detect everything as well.
Once the script is dot-sourced or pasted in an elevated powershell instance you can run it by calling Install-VB6.
It also has the following parameters if you want to override any default behaviour:
Parameter
Type
Usage
Vb6InstallerPath
String
Path of main VB6 Installer folder
SP6InstallerPath
String
Path of Service Pack 6 Installer folder
SkipMouseWheel
Switch
Skip installing the Mouse Wheel Fixer folder
MouseWheelPath
String
Path of Mouse Wheel fixer. Ignored if -SkipMouseWheel is specified
Regsvr32Path
String
Path to regsvr32.exe. Uses '%SYSTEMROOT%\SysWoW64\regsvr32.exe' if not specified
RegEditPath
String
Path to regedit.exe. '%SYSTEMROOT%\regedit.exe' if not specified
OrganizationName
String
Sets the organization name in the VB6 installer
Notes:
The VB6 and SP6 installer don't like being run from a network drive, so the script will stop if it detects one of the install folders is not on a local drive.
I've only tested this with VB6 Pro, not VB6 Enterprise.
It doesn't install MSDN.
Install-VB6.ps1
#Requires -RunAsAdministrator
#Requires -Version 3
<#
.SYNOPSIS
Installs VB6 to the computer.
.DESCRIPTION
Installs VB6 ide with Service Pack 6 and (optional) Mouse Wheel Fix to the local computer.
.PARAMETER Vb6InstallerPath
The path to the VB6 installer folder.
.PARAMETER SP6InstallerPath
The path the the Service Pack 6 installer folder.
.PARAMETER SkipMouseWheel
Skip installing the Mouse Wheel fix.
.PARAMETER MouseWheelPath
The path the Mouse wheel fix folder.
.PARAMETER Regsvr32Path
The path to RegSvr32.exe
.PARAMETER OrganizationName
The organization name
.PARAMETER RegEditPath
The path to regedit.exe
#>
Function Install-VB6{
[CmdletBinding()]
param (
[Parameter(Mandatory=$false)]
[string]$Vb6InstallerPath,
[Parameter(Mandatory=$false)]
[string]$SP6InstallerPath,
[Parameter(Mandatory=$false)]
[switch]$SkipMouseWheel,
[Parameter(Mandatory=$false)]
[string]$MouseWheelPath,
[Parameter(Mandatory=$false)]
[string]$Regsvr32Path,
[Parameter(Mandatory=$false)]
[string]$OrganizationName,
[Parameter(Mandatory=$false)]
[string]$RegEditPath
)
# Tests if the path is a local path. The installer doesn't like network paths.
function Test-LocalDrive{
[CmdletBinding()]
[OutputType([bool])]
param(
[Parameter(Mandatory=$true,
Position=0)]
[string]$Path
)
begin{
$localDrives = Get-WmiObject -Class Win32_logicaldisk -Filter "DriveType<>4" -Property "DeviceID" | Foreach-Object {$_.DeviceID.Replace(":", "")}
}
process{
if(!([bool](Test-Path -Path $Path))){
return $false
}
$item = Get-Item -Path $Path
$drive = $item.PSDrive
if($null -eq $drive){
return $false
}
return ($localDrives -contains $drive.Name)
}
}
function Search-ForFile{
[CmdletBinding()]
[OutputType([System.IO.FileInfo])]
param(
[Parameter(Mandatory=$true,
Position=0)]
[string]$File,
[Parameter(Mandatory=$true,
Position=1)]
[string]$CurrentLocation,
[switch]$IncludeSubDirectory
)
process{
$newPath = $currentLocation
if($IncludeSubDirectory.IsPresent){
$newPath = Join-Path -Path $newPath -ChildPath "*"
}
$newPath = Join-Path -Path $newPath -ChildPath $file
$item = #(Get-Item -Path $newPath)
if($null -eq $item -or $item.Count -eq 0 -or $null -eq $item[0]){
throw ("Could Not find the {0} file." -f $file)
}
return $item[0]
}
}
#region Setting Up File Paths
$currentLocation = $PSScriptRoot
if([System.String]::IsNullOrWhiteSpace($currentLocation)){
$currentLocation = (Get-Location)
}
if([System.String]::IsNullOrWhiteSpace($currentLocation)){
throw "Unable to determine current location"
}
if(!$PSBoundParameters.ContainsKey("Vb6InstallerPath") -or [System.String]::IsNullOrWhiteSpace($Vb6InstallerPath)){
if(!(Test-LocalDrive -Path ($currentLocation))){
Write-Error "The script cannot be ran from a network share."
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
$installerInfo = Search-ForFile -File "SETUP.EXE" -CurrentLocation $currentLocation -IncludeSubDirectory
$installFolder = $installerInfo.DirectoryName
}
else {
if(!(Test-LocalDrive -Path ($Vb6InstallerPath))){
Write-Error "The VB6 Installer Path cannot be a share."
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
$installFolder = $Vb6InstallerPath
$installerInfo = Search-ForFile -File "SETUP.EXE" -CurrentLocation $installFolder
}
$installer2Info = Search-ForFile -File "ACMSETUP.EXE" -CurrentLocation $installFolder -IncludeSubDirectory
$installLocation = $installerInfo.FullName
$install2Location = $installer2Info.FullName
if(!$PSBoundParameters.ContainsKey("SP6InstallerPath") -or [System.String]::IsNullOrWhiteSpace($SP6InstallerPath)){
if(!(Test-LocalDrive -Path ($currentLocation))){
Write-Error "The script cannot be ran from a network share."
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
$SP6Info = Search-ForFile -File "setupsp6.exe" -CurrentLocation $currentLocation -IncludeSubDirectory
$SP6Folder = $SP6Info.DirectoryName
}
else {
if(!(Test-LocalDrive -Path ($SP6InstallerPath))){
Write-Error "The SP6 Installer Path cannot be a network share."
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
$SP6Folder = $SP6InstallerPath
$SP6Info = Search-ForFile -File "setupsp6.exe" -CurrentLocation $SP6Folder
}
$SP6Location = $SP6Info.FullName
if(!$SkipMouseWheel.IsPresent){
if(!$PSBoundParameters.ContainsKey("MouseWheelPath") -or [System.String]::IsNullOrWhiteSpace($MouseWheelPath)){
if(!(Test-LocalDrive -Path ($currentLocation))){
Write-Error "The script cannot be ran from a network share."
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
$MouseWheelDllInfo = Search-ForFile -File "VB6IDEMouseWheelAddin.dll" -CurrentLocation $currentLocation -IncludeSubDirectory
$MouseWheelRegistryInfo = Search-ForFile -File "VBA Mouse Wheel Fix.reg" -CurrentLocation $currentLocation -IncludeSubDirectory
}
else {
if(!(Test-LocalDrive -Path ($SP6InstallerPath))){
Write-Error "The Mouse Wheel Path cannot be a network share."
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
$MouseWheelDllInfo = Search-ForFile -File "VB6IDEMouseWheelAddin.dll" -CurrentLocation $MouseWheelPath
$MouseWheelRegistryInfo = Search-ForFile -File "VBA Mouse Wheel Fix.reg" -CurrentLocation $MouseWheelPath
}
$MouseWheelDll = $MouseWheelDllInfo.FullName
$MouseWheelRegistry = $MouseWheelRegistryInfo.FullName
}
if(!$PSBoundParameters.ContainsKey("Regsvr32Path") -or [System.String]::IsNullOrWhiteSpace($Regsvr32Path)){
$regSvrPath = "$($env:systemroot)\SysWoW64\regsvr32.exe"
}
else{
$regSvrPath = $Regsvr32Path
}
if(!$PSBoundParameters.ContainsKey("RegEditPath") -or [System.String]::IsNullOrWhiteSpace($RegEditPath)){
$RegEditPath = "$($env:systemroot)\regedit.exe"
}
#endregion Setting Up File Paths
#region Test Required Installer Paths Exist
if(!([bool](Test-Path -Path $regSvrPath))){
Write-Error ("Unable to find '{0}'.`r`nThe exe must exist." -f $regSvrPath)
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
if(!([bool](Test-Path -Path $RegEditPath))){
Write-Error ("Unable to find '{0}'.`r`nThe exe must exist." -f $RegEditPath)
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
if(!$SkipMouseWheel.IsPresent){
if(!([bool](Test-Path -Path $MouseWheelDll))){
Write-Error ("Unable to find '{0}'.`r`nThe 'MouseWheel' Folder must be in the same directory as the install script and the file must exist." -f $MouseWheelDll)
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
if(!([bool](Test-Path -Path $MouseWheelRegistry))){
Write-Error ("Unable to find '{0}'.`r`nThe 'MouseWheel' Folder must be in the same directory as the install script and the file must exist." -f $MouseWheelRegistry)
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
}
if(!([bool](Test-Path -Path $installFolder))){
Write-Error ("Unable to find '{0}'.`r`nThe 'Installer' Folder must be in the same directory as the install script." -f $installFolder)
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
if(!([bool](Test-Path -Path $installLocation))){
Write-Error ("Unable to find '{0}'.`r`nThe 'Installer' Folder must be in the same directory as the install script and the file must exist." -f $installLocation)
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
if(!([bool](Test-Path -Path $install2Location))){
Write-Error ("Unable to find '{0}'.`r`nThe 'Installer' Folder must be in the same directory as the install script and the file must exist." -f $install2Location)
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
if(!([bool](Test-Path -Path $SP6Location))){
Write-Error ("Unable to find '{0}'.`r`nThe 'SP6' Folder must be in the same directory as the install script and the file must exist." -f $SP6Location)
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
return
}
#endregion Test Required Installer Paths Exist
#region Installer Compatibility
# The installer doesn't auto-elevate to run as an administrator.
# We are setting the required keys in the registry to force the installers to run as administrator
# Same as running the 'troubleshoot compatibilty' wizard and selecting the exe's to run as admins.
Write-Host "Setting compatibility mode on setup files."
$layersPath = "REGISTRY::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
if(![bool](Test-Path -Path $layersPath)){
New-Item -Path $layersPath -Force | Out-Null
}
$registryPath = Get-Item -LiteralPath $layersPath
if($null -eq $registryPath.GetValue($installLocation, $null)){
New-ItemProperty -Path $layersPath -Name $installLocation -Value "^ WINXPSP3" -PropertyType "String" -Force | Out-Null
}
if($null -eq $registryPath.GetValue($SP6Location, $null)){
New-ItemProperty -Path $layersPath -Name $SP6Location -Value "^ WINXPSP3" -PropertyType "String" -Force | Out-Null
}
#endregion Installer Compatibility
#region Previous Install Cleanup
# Locations and keys where old vb6 installs can live.
Write-Host "Cleaning up previous install."
$itemsToDelete = #(
"C:\Program Files*\Microsoft Visual Studio\Common",
"C:\Program Files*\Microsoft Visual Studio\MSDN",
"C:\Program Files*\Microsoft Visual Studio\MSDN98",
"C:\Program Files*\Microsoft Visual Studio\VB98",
"C:\Program Files*\Microsoft Visual Studio\VC98",
"C:\Program Files*\Microsoft Visual Studio\*.HTM",
"C:\Program Files*\Microsoft Visual Studio\*.TXT",
"C:\Program Files*\Common Files\Microsoft Shared\MSDesigners98",
"C:\Program Files*\Common Files\Microsoft Shared\MSDN",
"C:\Program Files*\Common Files\Microsoft Shared\VS98",
"C:\Program Files*\Common Files\Microsoft Shared\Wizards98",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\DevStudio",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\HTML Help Collections",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\MSVSDG",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\Visual Basic\6.0",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\Visual Component Manager",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\Visual Modeler",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Microsoft\VisualStudio\6.0",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\DevStudio",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\HTML Help Collections",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\MSVSDG",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Visual Basic\6.0",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Visual Component Manager",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\Visual Modeler",
"REGISTRY::HKEY_LOCAL_MACHINE\Software\Wow6432Node\Microsoft\VisualStudio\6.0",
"REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\DevStudio",
"REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\MSVSDG",
"REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\Visual Basic\6.0",
"REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\Visual Modeler",
"REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\VisualFoxPro",
"REGISTRY::HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\6.0"
)
$itemsToDelete | Where-Object { Test-Path -Path $_ } | Remove-Item -Force -Recurse | Out-Null
#endregion Previous Install Cleanup
#region Installer Registry Permissions
# The installer needs to be able to write to 'HKEY_CLASSES_ROOT\RDSServer.DataFactory\Clsid'
# but since the installer isn't built for windows and we have to force it to run as an administrator
# we have to give explicit permissions for your computers Administrators group to write to this key (and all its children)
Write-Host "Setting required permissions for installing user on registry."
$registryPermissionPath = "REGISTRY::HKEY_CLASSES_ROOT\RDSServer.DataFactory\Clsid"
Write-Host "`tSetting Up required information."
$acl = Get-ACL -Path $registryPermissionPath
$oldOwner = [System.Security.Principal.NTAccount]::new($acl.Owner)
$administratorIdentity = [System.Security.Principal.NTAccount]::new("Administrators")
Write-Host "`tGiving the script required permissions."
$import = '[DllImport("ntdll.dll")] public static extern int RtlAdjustPrivilege(ulong a, bool b, bool c, ref bool d);'
$ntdll = Add-Type -Member $import -Name NtDll -PassThru
$privileges = #{ SeTakeOwnership = 9; SeBackup = 17; SeRestore = 18 }
foreach ($i in $privileges.Values) {
$null = $ntdll::RtlAdjustPrivilege($i, 1, 0, [ref]0)
}
Write-Host "`tGettting The registry key."
$regKey = [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey("RDSServer.DataFactory\Clsid", 'ReadWriteSubTree', 'TakeOwnership')
# We force the Administrators group to be the owner on the key so we can then add required the permissions.
Write-Host "`tSetting Owner."
$acl.SetOwner($administratorIdentity)
$regKey.SetAccessControl($acl)
Write-Host "`tSetting Permission."
$permission = [System.Security.AccessControl.RegistryAccessRule]::new($administratorIdentity, "FullControl", "ContainerInherit", "InheritOnly", "Allow")
$acl.AddAccessRule($permission)
$permission2 = [System.Security.AccessControl.RegistryAccessRule]::new($administratorIdentity, "FullControl", "Allow")
$acl.AddAccessRule($permission2)
$regKey.SetAccessControl($acl)
# Reset the owner to clean-up
Write-Host "`tResetting Owner."
$acl.SetOwner($oldOwner)
$regKey.SetAccessControl($acl)
#endregion Installer Registry Permissions
#region Install
Write-Host "`tStarting Install."
$tempPath = [System.IO.Path]::GetTempPath()
$tempFolder = Join-Path -Path $tempPath -ChildPath ([System.Guid]::NewGuid().ToString("n"))
New-Item -Path $tempFolder -ItemType Directory -Force | Out-Null
$KeyFile = Join-Path -Path $tempFolder -ChildPath ("{0}.dat" -f [System.Guid]::NewGuid().ToString("n"))
$keyFileText = #"
REGEDIT4
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\6.0\Setup\Microsoft Visual Basic\SetupWizard]
"aspo"=dword:00000000
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\6.0\Setup\Microsoft Visual Basic\SetupWizard]
"aspo"=dword:00000000
"#
$keyFileText | Set-Content -Path $keyFile -Force
& $RegEditPath /S $KeyFile
[string[]]$installerArguments = ("/T", "VB98PRO.stf", "/S", $installFolder, "/n", ($env:USERNAME), "/k", "0000000000", "/b", "1", "/qn1")
if($PSBoundParameters.ContainsKey("OrganizationName") -and ![System.String]::IsNullOrWhiteSpace($OrganizationName)){
$installerArguments += "/o"
$installerArguments += $OrganizationName
}
Start-Process -FilePath $install2Location -wait -NoNewWindow -ArgumentList $installerArguments
Start-Process -FilePath $SP6Location -wait -NoNewWindow -ArgumentList ("/qn1")
Write-Host "Setting Vb6 Compatibility"
$vb6ExeLocations = #(Get-Item -Path "C:\Program Files*\Microsoft Visual Studio\VB98\VB6.EXE" | Select-Object -ExpandProperty FullName)
$registryPath = Get-Item -LiteralPath $layersPath
foreach($vb6ExeLocation in $vb6ExeLocations){
if($null -eq $registryPath.GetValue($vb6ExeLocation, $null)){
New-ItemProperty -Path $layersPath -Name $vb6ExeLocation -Value "^ WINXPSP3" -PropertyType "String" -Force | Out-Null
}
}
if(!$SkipMouseWheel.IsPresent){
Write-Host "Installing Mouse Wheel"
& $regSvrPath /s $MouseWheelDll
& $RegEditPath /S $MouseWheelRegistry
$registryHeaderText = #"
Windows Registry Editor Version 5.00
"#
$registryItemFormat = #"
[{0}\SOFTWARE\Microsoft\Visual Basic\6.0\Addins\VB6IDEMouseWheelAddin.Connect]
"FriendlyName"="MouseWheel Fix"
"LoadBehavior"=dword:00000003
"CommandLineSafe"=dword:00000000
"#
$users = Get-ChildItem -Path "REGISTRY::HKEY_USERS" | Where-Object {$_.Name -notlike "*_Classes"} | Select-Object -ExpandProperty Name
$content = $registryHeaderText
# Install for every user.
foreach($user in $users){
$content += ($registryItemFormat -f $user)
}
$MouseWheelApplyRegistry = Join-Path -Path $tempFolder -ChildPath ("{0}.reg" -f [System.Guid]::NewGuid().ToString("n"))
$content | Set-Content -Path $MouseWheelApplyRegistry -Force
Start-Process $RegEditPath -wait -NoNewWindow -ArgumentList ("/S", $MouseWheelApplyRegistry)
Write-Host "You will still need to enable Mouse Wheel fix in the VB6 IDE." -BackgroundColor Black -ForegroundColor Red
Write-Host "Open a Visual Basic project and go to 'Add-Ins' -> 'Add-In Manager...' " -BackgroundColor Black -ForegroundColor Red
Write-Host "Select 'MouseWheel Fix' and click 'Loaded/Unloaded' and 'Load on Startup'" -BackgroundColor Black -ForegroundColor Red
}
Remove-Item -Path $tempFolder -Force -Recurse | Out-Null
#endregion Install
Write-Host "Install Complete"
Write-Host -NoNewLine 'Press any key to continue...';
$null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');
}
Microsoft's support statement for the VB6 programming environment is here...
VB6 support statement

Configure IDE Proxy Settings

When running
tf proxy /configure
from the commandline, tfs sets the proxy settings based on AD sites set up within the TFS server.
If this is done before Visual Studio is run for the first time, it appears that VS takes these values by default. However, if you rerun the command, Visual Studio does not update with the new values.
I'd like to give my developers a batch file that configures their proxy settings for the office they are currently in. So that they could easily set up the values when they are in different offices, or if they are working remotely.
I've written the below:
#echo off
set TFDIR=%vs120comnTools%..\IDE
set Path=%Path%;%TFDIR%
tf proxy /enabled:false
echo[
echo Configuring Proxy
tf proxy /configure /collection:[MyUrl]
PAUSE
If I run this, it does appear to load the correct settings, and the tf proxy command returns the appropriate values. However, when I open Visual Studio and go to Tools >> Options >> Source Control >> Team Foundation Server, the proxy settings remain at the last values I set manually.
Is there a way to make the batch file update the visual studio settings.
Update
Thanks to Vickys answer below, I've realised that the problem isn't quite what I thought it was.
When I am running tf.exe, it is correctly updating the TFS Proxy settings for the installation of Visual Studio that is hosting the exe (i.e. the one I'm using the path to). However, it doesn't update the proxy configurations of the other installed visual studio installations.
Since I don't want to have to run the command for all installed versions, I'm looking for a way to make it update them all from a single command.
After you run the batch file, you need to restart Visual Studio.
Thanks to Vickys answer, I have been able to determine the tf.exe will update the TFS settings for the IDE that it is hosted by. e.g. if you are running /14.0/Common7/IDE/tf.exe, it will update the settings for Visual Studio 2015. It won't, however, update 2013, 2012, etc.
I have written the below powershell script that will update the other instances. You will need to update the [MyUrl] Value with the appropriate url for your TFS collection
#TODO: Replace [MyUrl] With the collection Url
#Add New Versions to this list when new versions of VS are released
$VsVersionsToDisable = "10.0", "11.0", "12.0", "14.0"
[System.Collections.ArrayList]$VsVersions = $VsVersionsToDisable
[String]$VsProxyVersionToUse = ""
#Find the Highest installed VS Version, and use it for the TFS.exe Command.
foreach ($version in $VsVersions | Sort-Object -Descending)
{
$keyPath = "HKCU:\Software\Microsoft\VisualStudio\$version`_Config"
If (Test-Path $keyPath)
{
$aliasPath = Get-ItemProperty -Path $keyPath | Select-Object `
-ExpandProperty InstallDir
$proxyPath = Join-Path $aliasPath "tf.exe"
set-alias proxyTF $proxyPath
#Remove the VS Version we're using from the array
#the command will auto-set this value, so we don't need to manually set it.
$VsVersions.Remove($version)
$VsProxyVersionToUse = $version
break
}
}
#Gets the last Check time from the Auto-Configuration, to update the other
#versions
function Get-ProxyLastCheckTime()
{
return Get-ItemProperty `
"HKCU:\Software\Microsoft\VisualStudio\$VsProxyVersionToUse\TeamFoundation\SourceControl\Proxy" `
| Select-Object -ExpandProperty LastCheckTime
}
#For each installed version, updates the proxy settings.
function Set-VSIDEConfig
(
[String]
[Parameter(Mandatory=$true)]
$proxyUrl
)
{
$lastCheckTime = Get-ProxyLastCheckTime
foreach ($version in $VsVersions)
{
Push-Location
$regPath = "HKCU:\Software\Microsoft\VisualStudio\$version\TeamFoundation\SourceControl\Proxy"
if (Test-Path $regPath)
{
Write-Output "Updating Proxy IDE Settings for VS $version"
Set-Location $regPath
Set-ItemProperty . Enabled $true
Set-ItemProperty . Url $proxyUrl
Set-ItemProperty . AutoConfigured $true
Set-ItemProperty . LastCheckTime $lastCheckTime
Set-ItemProperty . LastConfigureTime $lastCheckTime
}
Pop-Location
}
}
#Disables the Current proxy Settings.
function Disable-VSIDEConfig()
{
foreach ($version in $VsVersionsToDisable)
{
Push-Location
$regPath = "HKCU:\Software\Microsoft\VisualStudio\$version\TeamFoundation\SourceControl\Proxy"
if (Test-Path $regPath)
{
Write-Output "Disabling Proxy IDE Settings for VS $version"
Set-Location $regPath
Set-ItemProperty . Enabled $false
}
Pop-Location
}
Write-Output ""
}
#Process the response from the Proxy command.
function Process-ProxyResult
(
[String[]]
[Parameter(Mandatory=$true)]
$result
)
{
$resultUrl = $result | Select -Last 1
if ($resultUrl -match "Successfully configured proxy (?<content>.*)\.")
{
$url = $matches["content"].Trim()
#Update the IDE Settings with the new proxy
Set-VSIDEConfig $url
}
Write-Output ""
}
#Run the TFS Proxy Setup.
function Set-TFSProxy()
{
#First, Disable the proxy settings
proxyTF proxy /enabled:$false
Disable-VSIDEConfig
Write-Output "Getting Proxy data from Team02"
#TODO: Replace [MyUrl] With the collection Url
$output = proxyTF proxy /configure /collection:[MyUrl] 2>&1
Write-Output $output
Write-Output ""
Process-ProxyResult $output
}
#Run it by default.
Set-TFSProxy

Resources