Optimize your experience with RingCentral Video. Learn more.
Over time, user environments can become cluttered with multiple versions of the RingCentral app. Powershell commands provide a way to remove these legacy versions. Running this script as an administrator removes any system-wide installations of the RingCentral app, after which, the current app version can be installed. When an admin runs the script on a computer with multiple users, RingCentral will be uninstalled for all.
This article shows two scripts:
- The first uninstalls all versions of the RingCentral app.
- The second uninstalls the RingCentral classic app.
Download PowerShell script
This script cleans up the following apps running on a Windows operating system:
- RingCentral Meetings app
- RingCentral Meetings Outlook plugin
- RingCentral Classic app
- RingCentral app
- RingCentral Phone
Usage notes
The script should be run while logged in as a system administrator. All previous versions of the RingCentral app and any shortcuts will be removed for all users.
When running this script, RingCentral MVP will be unresponsive.
Legal notice
Please read this disclaimer carefully before using this script. This script is open-source and subject to the terms of the MIT license.
This script is provided as a tool for IT Administrators to programatically remove legacy RingCentral Classic App from End Users’ devices.
We also highly recommend that you first test this script to ensure that it achieves the desired results.
RingCentral makes no representation as to the script containing any errors or bugs. Any bugs or errors in the script may produce an undesirable outcome. Additionally, any modification or unintentional change made by you may have undesirable effects. If you discover any issue with the script, you should immediately cease use and manage the removal of RingCentral Classic application manually.
Your use of this software is undertaken at your own risk. To the full extent permitted under law, RingCentral will not be liable for any loss or damage of whatever nature (direct, indirect, consequential or other) caused by the use of this script.
Uninstalling Windows versions of RingCentral apps
Preliminary script
This preliminary script must be run prior to executing any of those that follow.
- The first line ensures that any powershell errors will be captured in the log file in addition to being displayed in the powershell window.
- The second line sets the location of the log file. It should be set to an area that exists on the user’s local system.
- The third line sets the date/time format to use in the log file.
- The script then checks that it is running as an administrator, and stops if it isn’t.
$ErrorActionPreference = «Stop»
$logfile = «C:temp$(gc env:computername)-remove-RCApps.log»
$dtFormat = ‘dd-MMM-yyyy HH:mm:ss’
add-content $logfile -value «—————————————————————————————————-«
add-content $logfile -value «$(Get-Date -Format $dtFormat) Attempting to remove RC apps»
$isAdmin = (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
add-content $logfile -value «$(Get-Date -Format $dtFormat) Running in Administrator context: $isAdmin»
if (!$isAdmin){
add-content $logfile -value «$(Get-Date -Format $dtFormat) Script must be executed as an administrator: powershell.exe -noprofile -executionpolicy Bypass -file `»admin.ps1`»»
exit(-5)
To stop any RingCentral applications that may be running
This part of the script stops any of the processes on the current computer system for any currently logged on users. RingCentral applications to which the administrator has access are removed.
get-process | where-object {$_.Company -like «*RingCentral*» -or $_.Path -like «*RingCentral*»} | stop-process -ErrorAction ignore -Force
To stop any RingCentral installed applications that the administrator can remove
foreach ($app in (Get-WmiObject -Class Win32_Product | Where-Object{$_.Vendor -like «*RingCentral*»})) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Attempting to uninstall $($app)»
try {
$app.Uninstall() | Out-Null
} catch {
add-content $logfile -value $_
To remove any system uninstall keys
This section of the script cleans the Uninstall registry keys to remove any entries for RingCentral applications. If the uninstall section includes an uninstaller, then the script attempts to use that before removing the registry key.
$paths = @(«HKLM:SOFTWAREMicrosoftWindowsCurrentVersionUninstall»,
«HKLM:SOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionUninstall»)
foreach($path in $paths) {
if (test-path($path)) {
$list = Get-ItemProperty «$path*» | Where-Object {$_.DisplayName -like «*RingCentral*»} | Select-Object -Property PSPath, UninstallString
foreach($regkey in $list) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Examining Registry Key $($regkey.PSpath)»
try {
$cmd = $regkey.UninstallString
if ($cmd -like «msiexec.exe*») {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Uninstall string is using msiexec.exe»
if ($cmd -notlike «*/X*») {
add-content $logfile -value «$(Get-Date -Format $dtFormat) no /X flag — this isn’t for uninstalling»
$cmd = «»
} #don’t do anything if it’s not an uninstall
elseif ($cmd -notlike «*/qn*») {
add-content $logfile -value «$(Get-Date -Format $dtFormat) adding /qn flag to try and uninstall quietly»
$cmd = «$cmd /qn»
} #don’t display UI
}
if ($cmd) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) executing $($cmd)»
cmd.exe /c «$($cmd)»
add-content $logfile -value «$(Get-Date -Format $dtFormat) done»
}
} catch {
add-content $logfile -value $_
}
}
$list = Get-ItemProperty «$path*» | Where-Object {$_.DisplayName -like «*RingCentral*»} | Select-Object -Property PSPath
foreach($regkey in $list) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Removing Registry Key $($regkey.PSpath)»
try {
remove-item $regkey.PSPath -recurse -force
} catch {
add-content $logfile -value $_
}
}
} ##else { add-content $logfile -value «$(Get-Date -Format $dtFormat) Path $($item) not found» }
}
Add shortcut to HKEY_USERS
This section of the script adds a shortcut to the HKEY_USERS registry hive, and then sets variables for standard Windows locations.
New-PSDrive -PSProvider registry -Root HKEY_USERS -Name HKU | Out-Null
if (test-path(${Env:ProgramFiles(x86)})) { $pf86 = ${Env:ProgramFiles(x86)} } else { $pf86 = «C:Program Files (x86)» }
add-content $logfile -value «$(Get-Date -Format $dtFormat) Program Files (x86) location: $($pf86)»
if (test-path(${Env:ProgramFiles})) { $pf = ${Env:ProgramFiles} } else { $pf = «C:Program Files» }
add-content $logfile -value «$(Get-Date -Format $dtFormat) Program Files location: $($pf)»
if (test-path(${Env:ProgramData})) { $pd = ${Env:ProgramData} } else { $pd = «C:ProgramData» }
add-content $logfile -value «$(Get-Date -Format $dtFormat) ProgramData location: $($pd)»
if (test-path(${Env:PUBLIC})) { $pub = ${Env:PUBLIC} } else { $pub = «C:UsersPublic» }
add-content $logfile -value «$(Get-Date -Format $dtFormat) Public profile location: $($pub)»
if (test-path(${Env:SystemRoot})) { $win = ${Env:SystemRoot} } else { $win = «C:Windows» }
add-content $logfile -value «$(Get-Date -Format $dtFormat) Windows root location: $($win)»
Populate the lists of items to remove
In this section, the script lets you set the brand to allow removal of various branded items. Set a collection of items to remove from HKEY_LOCAL_MACHINE and then remove each one if it exists.
To see the result of every test, uncomment the ##else statement.
$Brand = «RingCentral» #RingCentral/TELUS/ATT/Avaya/BT/Rainbow/Unify
add-content $logfile -value «$(Get-Date -Format $dtFormat) Brand set to: $($Brand)»
$HKLM = [System.Collections.ArrayList]@()
$HKLM.add(«HKLM:SOFTWARE$Brand») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClasses.rcrecord») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClasses.zoomrc») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesMIMEDatabaseContent Typeapplication/x-rcmtg-launcher») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesRCLauncher») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesRingCentralMeetingsRecording») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesrcapp») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesrcmobile») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesrcsp») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesrcuk») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesrcvdt») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesRingCentral.callto») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesRingCentral.fax») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesRingCentral.rcmobile») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesRingCentral.rcsp») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesRingCentral.rcuk») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClassesRingCentral.tel») | Out-Null
$HKLM.add(«HKLM:SOFTWAREClasseszoomrc») | Out-Null
$HKLM.add(«HKLM:SOFTWAREIM ProvidersRCIM») | Out-Null
$HKLM.add(«HKLM:SOFTWAREInternetPrinters») | Out-Null
$HKLM.add(«HKLM:SOFTWAREMicrosoftOfficeOutlookAddinsRingCentralForOutlook») | Out-Null
$HKLM.add(«HKLM:SOFTWARERingCentralForOutlook») | Out-Null
$HKLM.add(«HKLM:SOFTWARERingCentralInternetFax») | Out-Null
$HKLM.add(«HKLM:SOFTWARERingCentralMeetings») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432Node$Brand») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClasses.rcrecord») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClasses.zoomrc») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesMIMEDatabaseContent Typeapplication/x-rcmtg-launcher») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesRCLauncher») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesRingCentralMeetingsRecording») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesrcapp») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesrcmobile») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesrcsp») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesrcuk») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesrcvdt») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesRingCentral.callto») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesRingCentral.fax») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesRingCentral.rcmobile») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesRingCentral.rcsp») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesRingCentral.rcuk») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClassesRingCentral.tel») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeClasseszoomrc») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeIM ProvidersRCIM») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeInternetPrinters») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeMicrosoftOfficeOutlookAddinsRingCentralForOutlook») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeRingCentralForOutlook») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeRingCentralInternetFax») | Out-Null
$HKLM.add(«HKLM:SOFTWAREWOW6432NodeRingCentralMeetings») | Out-Null
foreach ($regkey in $HKLM) {
try {
if (test-path($regkey)) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Removing Registry Key $($regkey)»
remove-item $regkey -recurse -force
} ##else { add-content $logfile -value «$(Get-Date -Format $dtFormat) Registry Key $($regkey) not found» }
} catch {
add-content $logfile -value $_
}
}
Set folders to be removed
This part of the script lets you set a collection of computer-level folders/files to be removed. This uses the variables set up in the Add shortcut to HKEY_Users section of the script for the standard Windows locations, and checking 64-bit and 32-bit locations.
Check whether the path exists and recursively force removal if it does.
Again, ##else can be uncommented to check every removal.
$MachineFolders = [System.Collections.ArrayList]@()
$MachineFolders.add(«$pdGlip») | Out-Null
$MachineFolders.add(«$pdMicrosoftWindowsStart MenuPrograms*RingCentral*») | Out-Null
$MachineFolders.add(«$pf86$BrandSoftPhoneApp») | Out-Null
$MachineFolders.add(«$pf86Common FilesRingCentral») | Out-Null
$MachineFolders.add(«$pf86Glip») | Out-Null
$MachineFolders.add(«$pf86RingCentral Classic Installer») | Out-Null
$MachineFolders.add(«$pf86RingCentral Installer») | Out-Null
$MachineFolders.add(«$pf86RingCentralForOutlook») | Out-Null
$MachineFolders.add(«$pf86RingCentralMeetings») | Out-Null
$MachineFolders.add(«$pf$BrandSoftPhoneApp») | Out-Null
$MachineFolders.add(«$pfCommon FilesRingCentral») | Out-Null
$MachineFolders.add(«$pfGlip») | Out-Null
$MachineFolders.add(«$pfRingCentral Classic Installer») | Out-Null
$MachineFolders.add(«$pfRingCentral Installer») | Out-Null
$MachineFolders.add(«$pfRingCentralForOutlook») | Out-Null
$MachineFolders.add(«$pfRingCentralMeetings») | Out-Null
$MachineFolders.add(«$pubDesktopRingCentral*.lnk») | Out-Null
$MachineFolders.add(«$winPrefetch*GLIP*.pf») | Out-Null
$MachineFolders.add(«$winPrefetch*RINGCENTRAL*.pf») | Out-Null
$MachineFolders.add(«$winPrefetch*SOFTPHONE*.pf») | Out-Null
foreach ($item in $MachineFolders) {
try {
if (test-path($item)) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Removing $($item)»
remove-item $item -recurse -force
} ##else { add-content $logfile -value «$(Get-Date -Format $dtFormat) Path $($item) not found» }
} catch {
add-content $logfile -value $_
}
}
Loop through HKLM key to remove RC entries
This part of the script reviews the specified paths, examining the property and value for mentions of RingCentral, and removing if it finds the string. Firewall rules are removed if they were set up by a RingCentral installer.
$paths = @(«HKLM:SOFTWAREMicrosoftWindowsCurrentVersionInstallerFolders»,
«HKLM:SOFTWAREMicrosoftWindowsCurrentVersionUFHARP»,
«HKLM:SYSTEMControlSet001ServicesSharedAccessParametersFirewallPolicyFirewallRules»,
«HKLM:SYSTEMCurrentControlSetServicesSharedAccessParametersFirewallPolicyFirewallRules»)
foreach($path in $paths) {
if (test-path($path)) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Checking registry path: $($path)»
Get-Item -Path $path | Select-Object -ExpandProperty Property | % {
$propValue = (Get-ItemProperty -Path «$path» -Name «$_»).»$_»
if (($_ -like «*RingCentral*») -or ($propValue -like «*RingCentral*»)) {
try {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Removing property: $($_) containing value: $($propValue)»
Remove-ItemProperty -path «$path» -Name $_
} catch {
add-content $logfile -value $_
}
}
}
} ##else { add-content $logfile -value «$(Get-Date -Format $dtFormat) Path $($item) not found» }
}
Build list of items that need to be removed for each user profile
In this part of the script, you set up the collections of user keys to be examined for each profile. Use HKEY_USERS and match by the user’s SID.
The users folders will look up the locations in the registry when working on removing RingCentral details for that user.
$HKU = [System.Collections.ArrayList]@()
$HKU.add(«HKU:%SID%SOFTWARE$Brand») | Out-Null
$HKU.add(«HKU:%SID%SOFTWARE584acf4c-ebc3-56fa-9cfd-586227f098ba») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREClientsInternet CallRingCentral for Windows») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREIM ProvidersRCIM») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREMicrosoftInternet ExplorerProtocolExecutezoomrc») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREMicrosoftInternet ExplorerZoom») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREMicrosoftWindowsCurrentVersionApplicationAssociationToastsrcapp_rcapp») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREMicrosoftWindowsCurrentVersionApplicationAssociationToastszoomrc_zoomrc») | Out-Null
$HKU.add(«HKU:%SID%SOFTWARERingCentral Softphone») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432Node$Brand») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeClassesMIMEDatabaseContent Typeapplication/x-rcmtg-launcher») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeClassesrcapp») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeClassesrcmobile») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeClassesrcvdt») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeClasseszoomrc») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeIM ProvidersRCIM») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeClientsInternet CallRingCentral for Windows») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeMicrosoftInternet ExplorerProtocolExecutezoomrc») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeMicrosoftInternet ExplorerZoom») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionApplicationAssociationToastsrcapp_rcapp») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionApplicationAssociationToastszoomrc_zoomrc») | Out-Null
$HKU.add(«HKU:%SID%SOFTWAREWOW6432NodeRingCentral Softphone») | Out-Null
$HKU.add(«HKU:%SID%_classes.rcrecord») | Out-Null
$HKU.add(«HKU:%SID%_classes.zoomrc») | Out-Null
$HKU.add(«HKU:%SID%_classesMIMEDatabaseContent Typeapplication/x-rcmtg-launcher») | Out-Null
$HKU.add(«HKU:%SID%_classesRCLauncher») | Out-Null
$HKU.add(«HKU:%SID%_classesRingCentralMeetingsRecording») | Out-Null
$HKU.add(«HKU:%SID%_classesRingCentralMeetingsRecording») | Out-Null
$HKU.add(«HKU:%SID%_classesrcapp») | Out-Null
$HKU.add(«HKU:%SID%_classesrcmobile») | Out-Null
$HKU.add(«HKU:%SID%_classesrcsp») | Out-Null
$HKU.add(«HKU:%SID%_classesrcuk») | Out-Null
$HKU.add(«HKU:%SID%_classesrcvdt») | Out-Null
$HKU.add(«HKU:%SID%_classesRingCentral.callto») | Out-Null
$HKU.add(«HKU:%SID%_classesRingCentral.fax») | Out-Null
$HKU.add(«HKU:%SID%_classesRingCentral.rcmobile») | Out-Null
$HKU.add(«HKU:%SID%_classesRingCentral.rcsp») | Out-Null
$HKU.add(«HKU:%SID%_classesRingCentral.rcuk») | Out-Null
$HKU.add(«HKU:%SID%_classesRingCentral.tel») | Out-Null
$HKU.add(«HKU:%SID%_classeszoomrc») | Out-Null
$UserFolders = [System.Collections.ArrayList]@()
$UserFolders.add(«%desktop%RingCentral Classic.lnk») | Out-Null
$UserFolders.add(«%desktop%RingCentral Meetings.lnk») | Out-Null
$UserFolders.add(«%desktop%RingCentral.lnk») | Out-Null
$UserFolders.add(«%local%$Brand») | Out-Null
$UserFolders.add(«%local%$BrandSoftPhoneApp») | Out-Null
$UserFolders.add(«%local%Glip») | Out-Null
$UserFolders.add(«%local%ProgramsRingCentral») | Out-Null
$UserFolders.add(«%local%RingCentral») | Out-Null
$UserFolders.add(«%local%RingCentralRingCentral Classic») | Out-Null
$UserFolders.add(«%local%RingCentralRingCentral») | Out-Null
$UserFolders.add(«%local%SquirrelTemp») | Out-Null
$UserFolders.add(«%local%TempGlip Crashes») | Out-Null
$UserFolders.add(«%local%ringcentral-updater») | Out-Null
$UserFolders.add(«%roaming%.rc-persist») | Out-Null
$UserFolders.add(«%roaming%Glip») | Out-Null
$UserFolders.add(«%roaming%JabraSDK») | Out-Null
$UserFolders.add(«%roaming%MicrosoftWindowsStart MenuProgramsRingCentral Meetings») | Out-Null
$UserFolders.add(«%roaming%MicrosoftWindowsStart MenuProgramsRingCentral») | Out-Null
$UserFolders.add(«%roaming%MicrosoftWindowsStart MenuProgramsRingCentral*.lnk») | Out-Null
$UserFolders.add(«%roaming%MicrosoftWindowsStart MenuProgramsRingCentralRingCentral Classic.lnk») | Out-Null
$UserFolders.add(«%roaming%MicrosoftWindowsStart MenuProgramsStartupRingCentral*.lnk») | Out-Null
$UserFolders.add(«%roaming%RingCentral») | Out-Null
$UserFolders.add(«%roaming%RingCentralMeetings») | Out-Null
$UserFolders.add(«%roaming%RingCentrallogs») | Out-Null
$UserFolders.add(«%roaming%ZoomSDK») | Out-Null
$UserFolders.add(«%roaming%com.ringcentral.rcoutlook») | Out-Null
For each user profile on the computer, remove registry keys and associated folders for each RingCentral application
In this part of the script, you will manually uninstall RingCentral applications for each user profile on the system.
Refer to a list of users from the registry and check which hives are loaded and which are not, including system profiles as some components may be installed there. The default profile is added if any settings have been applied for newly created users.
If the hive is not loaded (i.e. the user is not logged in) then the script loads the user’s NTUSER.dat details and UsrClass.dat so that the registry keys can be updated.
The script also finds the locations of the user’s desktop, appdata and local appdata folders to be able to remove the folders created by the EXE installations.
add-content $logfile -value «$(Get-Date -Format $dtFormat) Removing applications for all user profiles»
$ProfileList = Get-ItemProperty ‘HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionProfileList*’ | Select-Object @{name=»SID»;expression={$_.PSChildName}}, @{name=»UserProfile»;expression={«$($_.ProfileImagePath)»}}, @{name=»Username»;expression={$_.ProfileImagePath -replace ‘^(.*[\/])’, »}}
$DefaultProfile = «» | Select-Object SID, UserProfile, Username
$DefaultProfile.SID = «.DEFAULT»
$DefaultProfile.UserProfile = «$pub..Default»
$DefaultProfile.UserName = «Default»
$ProfileList += $DefaultProfile
$LoadedHives = Get-ChildItem HKU: | Where-Object {$_.PSChildname -match $PatternSID} | Select-Object @{name=»SID»;expression={$_.PSChildName}}
$UnloadedHives = Compare-Object $ProfileList.SID $LoadedHives.SID | Select-Object @{name=»SID»;expression={$_.InputObject}}, UserHive, Username
foreach ($item in $ProfileList) {
try {
if ($item.SID -in $UnloadedHives.SID) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Loading profile $($item.username) — located at $($item.UserProfile)ntuser.dat»
reg load HKU$($item.SID) «$($item.UserProfile)ntuser.dat» | Out-Null
} else {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Checking profile $($item.username)»
}
$folders = «HKU:$($item.sid)SOFTWAREMicrosoftWindowsCurrentVersionExplorerUser Shell Folders»
$desktop = (Get-Item -Path $folders).GetValue(«Desktop», «$($item.UserProfile)Desktop», «DoNotExpandEnvironmentNames») -replace «%USERPROFILE%», $item.UserProfile
add-content $logfile -value «$(Get-Date -Format $dtFormat) User Desktop location: $($desktop)»
$local = (Get-Item -Path $folders).GetValue(«Local AppData», «$($item.UserProfile)AppDataLocal», «DoNotExpandEnvironmentNames») -replace «%USERPROFILE%», $item.UserProfile
add-content $logfile -value «$(Get-Date -Format $dtFormat) User Local AppData location: $($local)»
$roaming = (Get-Item -Path $folders).GetValue(«AppData», «$($item.UserProfile)AppDataRoaming», «DoNotExpandEnvironmentNames») -replace «%USERPROFILE%», $item.UserProfile
add-content $logfile -value «$(Get-Date -Format $dtFormat) User AppData location: $($roaming)»
if ($item.SID -in $UnloadedHives.SID) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Loading user classes for profile $($item.username) — located at $($local)MicrosoftWindowsUsrClass.dat»
reg load HKU$($item.SID)_classes «$($local)MicrosoftWindowsUsrClass.dat» | Out-Null
}
Remove registry keys
Remove registry keys and the specified file system folders. Uncomment ##else where applicable to see every check made in the log file.
foreach ($regkey in $HKU) {
try {
$key = $regkey -replace «%SID%», $item.SID
if (test-path($key)) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Removing Registry Key $($key)»
remove-item $key -recurse -force
} ##else { add-content $logfile -value «$(Get-Date -Format $dtFormat) Registry Key $($key) not found» }
} catch {
add-content $logfile -value $_
}
}
foreach ($path in $UserFolders) {
$temp = (($path -replace «%roaming%», $roaming) -replace «%local%», $local) -replace «%desktop%», $desktop
try {
if (test-path($temp)) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Removing $($temp)»
remove-item $temp -recurse -force
} ##else { add-content $logfile -value «$(Get-Date -Format $dtFormat) Path $($temp) not found» }
} catch {
add-content $logfile -value $_
}
}
Remove any user uninstall keys
Remove any uninstall entries so the programs don’t appear in add/remove programs. Also, remove from the Installer sections of the registry to ensure that reinstalling doesn’t prompt the user to remove/repair the software.
$paths = @(«HKU:$($item.sid)SOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionUninstall», «HKU:$($item.sid)SOFTWAREMicrosoftWindowsCurrentVersionUninstall»)
foreach($path in $paths) {
if (test-path($path)) {
$list = Get-ItemProperty «$path*» | Where-Object {$_.DisplayName -like «*RingCentral*»} | Select-Object -Property PSPath
foreach($regkey in $list) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Removing Uninstall Registry Key $($regkey.PSPath)»
try {
remove-item $regkey.PSPath -recurse -force
} catch {
add-content $logfile -value $_
}
}
} ##else { add-content $logfile -value «$(Get-Date -Format $dtFormat) Path $($item) not found» }
}
Remove any user install keys in the user hive and the user data part of the local computer
This part of the script checks the specified registry keys, removing the property if it or its value contains RingCentral. If the user wasn’t logged in, then the loaded registry hives are unloaded.
$paths = @(«HKU:$($item.sid)SOFTWAREWOW6432NodeMicrosoftInstallerProducts», «HKU:$($item.sid)SOFTWAREMicrosoftInstallerProducts»)
foreach($path in $paths) {
if (test-path($path)) {
$list = Get-ItemProperty «$path*» | Where-Object {$_.ProductName -like «*RingCentral*»} | Select-Object -Property PSPath
foreach($regkey in $list) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Removing Install Registry Key $($regkey.PSPath)»
try {
remove-item $regkey.PSPath -recurse -force
} catch {
add-content $logfile -value $_
}
}
} ##else { add-content $logfile -value «$(Get-Date -Format $dtFormat) Path $($item) not found» }
}
$paths = @(«HKLM:SOFTWAREWOW6432NodeMicrosoftWindowsCurrentVersionInstallerUserData$($item.sid)Products»,
«HKLM:SOFTWAREMicrosoftWindowsCurrentVersionInstallerUserData$($item.sid)Products»)
foreach($path in $paths) {
if (test-path($path)) {
$list = Get-ItemProperty «$path**» | Where-Object {$_.Publisher -like «*RingCentral*»} | Select-Object -Property PSParentPath
foreach($regkey in $list) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Removing Install Registry Key $($regkey.PSParentPath)»
try {
remove-item $regkey.PSParentPath -recurse -force
} catch {
add-content $logfile -value $_
}
}
} ##else { add-content $logfile -value «$(Get-Date -Format $dtFormat) Path $($item) not found» }
Loop through the keys and remove any RingCentral entries
$paths = @(«HKU:$($item.sid)_classesLocal SettingsSoftwareMicrosoftWindowsShellMuiCache»,
«HKU:$($item.sid)SOFTWAREMicrosoftWindowsCurrentVersionExplorerFeatureUsageAppBadgeUpdated»,
«HKU:$($item.sid)SOFTWAREMicrosoftWindowsCurrentVersionUFHSHC»)
foreach($path in $paths) {
if (test-path($path)) {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Checking registry path: $($path)»
Get-Item -Path $path | Select-Object -ExpandProperty Property | % {
$propValue = (Get-ItemProperty -Path «$path» -Name «$_»).»$_»
if (($_ -like «*RingCentral*») -or ($propValue -like «*RingCentral*»)) {
try {
add-content $logfile -value «$(Get-Date -Format $dtFormat) Removing property: $($_) containing value: $($propValue)»
Remove-ItemProperty -path «$path» -Name $_
} catch {
add-content $logfile -value $_
}
}
}
} ##else { add-content $logfile -value «$(Get-Date -Format $dtFormat) Path $($item) not found» }
}
if ($item.SID -in $UnloadedHives.SID) {
[gc]::Collect()
add-content $logfile -value «$(Get-Date -Format $dtFormat) Unloading profile»
reg unload HKU$($item.SID) | Out-Null
reg unload HKU$($item.SID)_classes | Out-Null
}
} catch {
add-content $logfile -value $_
}
}
Reinstall applications
To reinstall applications, if desired, remove comment (#) prior to running, including the log file comment. Check to confirm that the path to the MSI file is correct.
Note: The EXE files should not be deployed using this script, as doing so installs the application for the administrator account, not the user account.
add-content $logfile -value «$(Get-Date -Format $dtFormat) Installing required applications»
#add-content $logfile -value «$(Get-Date -Format $dtFormat) Installing RingCentral MSI app quietly»
#cmd.exe /c ‘MSIEXEC.EXE /i «RingCentral-x64.msi» /qn’
#add-content $logfile -value «$(Get-Date -Format $dtFormat) Installing RingCentral Meetings MSI app quietly»
#cmd.exe /c ‘MSIEXEC.EXE /i «RCMeetingsClientSetup.msi» /qn’
#add-content $logfile -value «$(Get-Date -Format $dtFormat) Installing RingCentral Phone MSI app quietly»
#cmd.exe /c ‘MSIEXEC.exe /i «RingCentral-Phone-21.1.0.msi» ALLUSERS=1 /qn’
add-content $logfile -value «$(Get-Date -Format $dtFormat) End of install script»
Uninstalling only the RingCentral Classic app
Over time, user environments can become cluttered with multiple versions of the RingCentral classic app. Powershell commands provide a way to remove these legacy versions. Running a script as administrator removes any system-wide installations of the RingCentral app, after which the current app version can be installed. When an admin runs the script on a computer with multiple users, RingCentral Classic will be uninstalled for all.
Usage notes
The script should be run while logged in as a system administrator. All previous versions of RingCentral Classic and any shortcuts will be removed for all users. Additionally, the script has an option to remove directories that should only be used when it is confirmed that no user is storing files in them.
To remove the folder used by RC Classic, remove the character from the four lines in the script that begin with —Force. There are four lines where this occurs. The second causes the script to look for a 32-bit installation on a 64-bit machine, the third and fourth lines remove the remaining Message folders inside users AppData directory).
When running this script, RingCentral MVP will be unresponsive.
Legal notice
Please read this disclaimer carefully before using this script. This script is open-source and subject to the terms of the MIT license.
This script is provided as a tool for IT Administrators to programatically remove legacy RingCentral Classic App from End Users’ devices.
We also highly recommend that you first test this script to ensure that it achieves the desired results.
RingCentral makes no representation as to the script containing any errors or bugs. Any bugs or errors in the script may produce an undesirable outcome. Additionally, any modification or unintentional change made by you may have undesirable effects. If you discover any issue with the script, you should immediately cease use and manage the removal of RingCentral Classic application manually.
Your use of this software is undertaken at your own risk. To the full extent permitted under law, RingCentral will not be liable for any loss or damage of whatever nature (direct, indirect, consequential or other) caused by the use of this script.
Stop any RingCentral applications that may be running
This code attempts to stop the applications if they are currently running. If they aren’t running, the script might produce an error generated from trying to stop a process that doesn’t exist. If this happens, ignore the error.
Note: RingCentral MVP app processes also stop during this script execution.
stop-process -ProcessName «RingCentral» -ErrorAction ignore
stop-process -ProcessName «RingCentral Classic» -ErrorAction ignore
To uninstall any RingCentral Classic MSI installed applications
This part of the script uses Windows Management Instrumentation (WMI) to check for installed products where the name is RingCentral Classic. For each occurrence found, WMI calls the uninstall routine for that product. A user who has installed the MSI applications has permission to remove them.
Any output generated is discarded.
The invocation of Get-WmiObject can be slow, typically requiring at least 20-30 seconds to return the list. Get-WmiObject is likely to take at least 20 seconds to execute on a machine.
foreach ($app in (Get-WmiObject -Class Win32_Product | Where-Object{$_.Name -like «*RingCentral Classic*»})) {
$app.Uninstall() | Out-Null
To remove RingCentral Classic for every user on the computer
RingCentral Classic can be uninstalled for each user profile on a machine using this code. The uninstall string in the registry for RingCentralClassic allows an administrator to uninstall the application on behalf of the user.
$PatternSID = ‘S-1-5-21-d+-d+-d+-d+$’
$ProfileList = Get-ItemProperty ‘HKLM:SOFTWAREMicrosoftWindows NTCurrentVersionProfileList*’ |
Where-Object {$_.PSChildName -match $PatternSID} |
Select @{name=»SID»;expression={$_.PSChildName}}, @{name=»ProfileImagePath»;expression={$_.ProfileImagePath}},
@{name=»UserHive»;expression={«$($_.ProfileImagePath)ntuser.dat»}},
@{name=»Username»;expression={$_.ProfileImagePath -replace ‘^(.*[\/])’, »}}
$LoadedHives = Get-ChildItem registry::HKEY_USERS | where-object {$_.PSChildname -match $PatternSID} |
Select @{name=»SID»;expression={$_.PSChildName}}
$UnloadedHives = Compare-Object $ProfileList.SID $LoadedHives.SID |
Select @{name=»SID»;expression={$_.InputObject}}, UserHive, Username
foreach ($item in $ProfileList) {
if ($item.SID -in $UnloadedHives.SID) {
reg load HKU$($item.SID) $($item.UserHive) | Out-Null
}
Load user profiles
This part of the script loads each user profile that exists on the current computer system in turn and checks whether there is an uninstall section for Glip. If there is, then it executes the uninstaller string and removes the item from the registry. Optionally, it can also remove the Glip folder from the user profile. To enable this option, uncomment the two Remove-Item lines by removing the # character at the beginning of the line.
Once a user has been checked, the registry hive is unloaded again.
$glip = «registry::HKEY_USERS$($item.SID)SOFTWAREMicrosoftWindowsCurrentVersionUninstallGlip»
if (test-path($glip)) {
$uninstall = Get-ItemProperty -Path $glip
$cmd = $uninstall.QuietUninstallString
if (!$cmd) {
$cmd = $uninstall.UninstallString
}
if ($cmd) {
Invoke-Expression «& $cmd»
Start-Sleep -Seconds 10
Remove-Item $glip -ErrorAction SilentlyContinue
#Remove-Item -Force -ErrorAction SilentlyContinue «$(Split-Path $cmd.substring(1, $cmd.indexof(‘»‘, 1)))» -Recurse
}
}
Optional statements
The statements in this part of the script are optional. They allow for the removal of the various directories in the user profile, if needed. To remove the folder and its contents, uncomment the line by removing the # symbol at the start of the line.
If you are unsure about removing these folders, they can be left in place. This is the safest approach as these folders are left behind when the official uninstaller is run. However, for users who want a fresh start before proceeding, these are the folders to delete.
If these folders are removed and a RingCentral Classic app is then installed, the user will need to re-enter emergency address details.
$glip = «registry::HKEY_USERS$($item.SID)SOFTWAREWow6432NodeMicrosoftWindowsCurrentVersionUninstallGlip»
if (test-path($glip)) {
$uninstall = Get-ItemProperty -Path $glip
$cmd = $uninstall.QuietUninstallString
if (!$cmd) {
$cmd = $uninstall.UninstallString
}
if ($cmd) {
Invoke-Expression «& $cmd»
Start-Sleep -Seconds 10
Remove-Item $glip -ErrorAction SilentlyContinue
#Remove-Item -Force -ErrorAction SilentlyContinue «$(Split-Path $cmd.substring(1, $cmd.indexof(‘»‘, 1)))» -Recurse
}
}
if ($item.SID -in $UnloadedHives.SID) {
[gc]::Collect()
reg unload HKU$($item.SID) | Out-Null
}
$AppDataLocalGlipPath=»$($item.ProfileImagePath)AppDataLocalGlip»
$AppDataRoamingGlipPath=»$($item.ProfileImagePath)AppDataRoamingGlip»
if (test-path $AppDataLocalGlipPath) {
#Remove-Item -Force $AppDataLocalGlipPath -Recurse -ErrorAction SilentlyContinue
}
if (test-path $AppDataRoamingGlipPath) {
#Remove-Item -Force $AppDataRoamingGlipPath -Recurse -ErrorAction SilentlyContinue
}
}
-
Question
-
What’s the deal with these new windows firewall rules created for each «local user owner», that allow all ports and programs? How can I disable their creation?
Contact Support — All — windows.contactsupport_cw5n1h2byewy
Search — All — microsoft.windows.cortana_cw5n1h2byewy
Work or school account — Domain, Private — microsoft.aad.brokerplugin_cw5n1h2byewy
Your account — Domain, Private — microsoft.windows.cloudexperiencehost_cw5n1h2byewy
All replies
-
Hi JS2010,
How did you check the firewall information?
Here is my understanding:
«Contact Support»
It should be related to the Metro app «Contact Support». It is an app could be used to ask for help from Microsoft directly. If it is disabled, this app may not work.
«Search»
It is related to the Cortana app. If it is disabled, the Cortana may not work well.
«Work or school account»
It should be related to the Azure AD account. If it is disabled, the Azure AD account may not work well.
«Your account»
It should be related to the cloud service of your account(Microsoft account sync settings between machines).These seem to be new default firewall rules for Windows 10. If you don`t want to use those features, we could disable them in firewall with the UI or the command line «netsh advfirewall».
Control PanelAll Control Panel ItemsWindows FirewallAllow an app or feature through Windows FirewallIf you want to use those features, we`d better to keep them.
Best regard
Please remember to mark the replies as answers if they help.
If you have feedback for TechNet Subscriber Support, contact
tnmff@microsoft.com.-
Proposed as answer by
Friday, November 11, 2016 6:38 AM
-
Proposed as answer by
-
I have print stations with 20,000 of these firewall rules. The cpu of the Windows Firewall service is often very high. I am trying to delete them remotely with powershell running as system user. When I tried netsh I couldn’t find the rules
going by name. But for some reason system user can’t find the rules either even though administrators can:Remove-NetFirewallRule : No MSFT_NetFirewallRule objects found with property 'DisplayName' equal to 'Your account'. Verify the value of the property and retry. At C:Usersmyadminfirewall-clean.ps1:6 char:1 + Remove-NetFirewallRule -DisplayName "Your account" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : ObjectNotFound: (Your account:String) [Remove-Ne tFirewallRule], CimJobException + FullyQualifiedErrorId : CmdletizationQuery_NotFound_DisplayName,Remove-N etFirewallRule
Do these rules permit all the ports to be open?
-
Edited by
JS2010
Thursday, November 10, 2016 12:32 PM
-
Edited by
-
This seems to work as the system user. The displaynames of the rules appear different to system than to administrators:
remove-netfirewallrule -displayname "*Windows.ContactSupport*" remove-netfirewallrule -displayname "*Microsoft.Windows.Cortana*" remove-netfirewallrule -displayname "*Microsoft.AAD.BrokerPlugin*" remove-netfirewallrule -displayname "*Microsoft.Windows.CloudExperienceHost*"
-
Edited by
JS2010
Thursday, November 10, 2016 7:55 PM -
Proposed as answer by
MeipoXuMicrosoft contingent staff
Friday, November 11, 2016 6:38 AM
-
Edited by
-
Hi
JS2010,I am glad you have figured out the method to remove the firewall rules. As I pointed out before, removing those firewall rules may affect the related feature. Please be careful.
Best regards
Please remember to mark the replies as answers if they help.
If you have feedback for TechNet Subscriber Support, contact
tnmff@microsoft.com.-
Edited by
MeipoXuMicrosoft contingent staff
Friday, November 11, 2016 6:39 AM
-
Edited by
-
This is much faster:
netsh advfirewall firewall delete rule name=@{Windows.ContactSupport_10.0.10240.16384_neutral_neutral_cw5n1h2txyewy?ms-resource://Windows.ContactSupport/Resources/appDisplayName} netsh advfirewall firewall delete rule name=@{Microsoft.Windows.Cortana_1.4.8.176_neutral_neutral_cw5n1h2txyewy?ms-resource://Microsoft.Windows.Cortana/resources/DisplayName} netsh advfirewall firewall delete rule name=@{Microsoft.AAD.BrokerPlugin_1000.10240.16384.0_neutral_neutral_cw5n1h2txyewy?ms-resource://Microsoft.AAD.BrokerPlugin/resources/PackageDisplayName} netsh advfirewall firewall delete rule name=@{Microsoft.Windows.CloudExperienceHost_10.0.10240.16384_neutral_neutral_cw5n1h2txyewy?ms-resource://Microsoft.Windows.CloudExperienceHost/resources/appDescription}
-
I’m still looking to this. There are 8 other firewall rules (at least 8 unique displaynames of rules) made for each user that you can’t even see in the firewall control panel. Their names start with an «@» symbol. Plus 16 more
unique displaynames of rules in the configurableservicestore policystore. On some computers, I run out of memory in powershell just trying to count them:get-netfirewallrule -policystore configurableservicestore -all | measure-object
-
Hi JS2010,
If it is possible, please post back the rules here. I will try my best to explain the rules for you.
According to my experience, most of those new firewall rules are related to the metro apps. If you don`t want to use them, we could delete them directly.Best regards
Please remember to mark the replies as answers if they help.
If you have feedback for TechNet Subscriber Support, contact
tnmff@microsoft.com. -
It’s tempting to paste here all 80 or so metro app firewall rules per user. You can just pick a user’s sid and dump them all like this in powershell. Most of them are in the configurable service store and aren’t visible in the control panel.
What do they do? There’s a few visible in the firewall control panel with names «Search», «Work or school account», «Your account», and «Contact Support».get-netfirewallrule -owner $sid get-netfirewallrule -policystore configurableservicestore -owner $sid
-
Edited by
JS2010
Tuesday, November 15, 2016 3:47 PM
-
Edited by
-
Hi JS2010,
I tried to check the rules with command line «get-netfirewallrule «. Most of them should be related to the metro apps. The «Display name»
and «Description» tag should explain the rule.Best regards
Please remember to mark the replies as answers if they help.
If you have feedback for TechNet Subscriber Support, contact
tnmff@microsoft.com.-
Edited by
MeipoXuMicrosoft contingent staff
Thursday, November 17, 2016 5:57 AM
-
Edited by
-
Hmm, it doesn’t make much sense to me. When there are a lot of these rules, svchost.exe goes to maximum cpu (25%) for several minutes after a new user logs in. And the rules never go away, even after profiles are deleted.
get-netfirewallrule -owner S-1-5-21-1111111111-222222222-3333333333-4444 | select-object displayname,description DisplayName description ----------- ----------- Work or school account Work or school account Work or school account Work or school account Your account Your account Your account Your account Search Search the web and Windows Search Search the web and Windows Email and accounts Email and accounts Windows Default Lock Screen Windows Default Lock Screen Windows Spotlight Windows Spotlight Microsoft family restrictions Microsoft family restrictions Windows Feedback Windows Feedback Xbox Game UI Xbox Game UI Xbox Identity Provider Xbox Identity Provider Contact Support Contact Support Contact Support Contact Support PurchaseDialog Print Dialog get-netfirewallrule -owner S-1-5-21-1111111111-222222222-3333333333-4444 -policystore configurableservicestore | select-object displayname,description DisplayName description ----------- ----------- Work or school account Work or school account Work or school account Work or school account Work or school account Work or school account Work or school account Work or school account Work or school account Work or school account Work or school account Work or school account Work or school account Work or school account windows_ie_ac_001 Created by IE windows_ie_ac_001 Created by IE windows_ie_ac_001 Created by IE Your account Your account Your account Your account Your account Your account Your account Your account Your account Your account Your account Your account Your account Your account Windows Shell Experience Windows Shell Experience Windows Shell Experience Windows Shell Experience Search Search the web and Windows Search Search the web and Windows Search Search the web and Windows Search Search the web and Windows Search Search the web and Windows Search Search the web and Windows Search Search the web and Windows Search Search the web and Windows Email and accounts Email and accounts Email and accounts Email and accounts Email and accounts Email and accounts Bio Enrollment Bio Enrollment Bio Enrollment Bio Enrollment Windows Default Lock Screen Windows Default Lock Screen Windows Default Lock Screen Windows Default Lock Screen Windows Default Lock Screen Windows Default Lock Screen Assigned Access Lock app Launches above lock app when assigned access user logs in Assigned Access Lock app Launches above lock app when assigned access user logs in Windows Spotlight Windows Spotlight Windows Spotlight Windows Spotlight Windows Spotlight Windows Spotlight Microsoft family restrictions Microsoft family restrictions Microsoft family restrictions Microsoft family restrictions Microsoft family restrictions Microsoft family restrictions Windows Feedback Windows Feedback Windows Feedback Windows Feedback Windows Feedback Windows Feedback Xbox Game UI Xbox Game UI Xbox Game UI Xbox Game UI Xbox Game UI Xbox Game UI Xbox Identity Provider Xbox Identity Provider Xbox Identity Provider Xbox Identity Provider Xbox Identity Provider Xbox Identity Provider Contact Support Contact Support Contact Support Contact Support Contact Support Contact Support Contact Support Contact Support Contact Support Contact Support Contact Support Contact Support Contact Support Contact Support Contact Support Contact Support PurchaseDialog Print Dialog PurchaseDialog Print Dialog PurchaseDialog Print Dialog
-
Edited by
JS2010
Thursday, November 17, 2016 4:09 PM
-
Edited by
-
Hi,
I know it’s been a few months, but we have just run into this problem in our computer labs and are discovering thousands of firewall rules as others have described above. Specifically, we are trying to address exactly the behavior that JS2010 is describing
with svchost.It doesn’t seem too complicated to write a ps script to clean up the existing entries to run on logout or something, but has anyone found a way to keep these rules from being added in the first place?
-
I think you’d have to completely break all the windows apps. I’ve seen a warning starting powershell when I tried deleting all the rules for the admin account though. To me the biggest problem is they stay around after deleting user profiles,
even in 2016 LTSB. And unlike netsh, when using powershell, the more rules there are, the slower deleting or adding rules happens, because it seems to process every rule. I ended up going directly to the registry to delete them in powershell.-
Edited by
JS2010
Thursday, March 9, 2017 7:39 PM
-
Edited by
-
Boy, you’re not kidding that it takes a long time to process firewall rules with Powershell! Sheesh! I think the estimate was something like 2 days for 10k rules, and we have machines with over 100k of these duplicate rules. At least with
Remove-ItemProperty it take as long as it needs and then a restart (or start…) of the firewall service puts the change in place. That’s a good call. We’re using SCCM to deploy a cleanup script that can be run while the computer is in use, and
if that’s successful, then I’ll try and share that for others that might run across this.These were the two registry locations that we found. I don’t know if you found more, so I thought I’d mention it.
HKLMSYSTEMControlSet001ServicesSharedAccessParametersFirewallPolicyFirewallRules
HKLMSYSTEMControlSet001ServicesSharedAccessParametersFirewallPolicyRestrictedServicesConfigurableSystem»
-
-
Edited by
JS2010
Thursday, March 9, 2017 7:39 PM
-
Edited by
-
Hey, I like your progress bar! I have to admit, I’ll probably borrow it myself for some other projects.
We did it slightly differently, but I think both approaches work just fine. So there were two things that guided our solution: (1) We found that the rules were duplicated at login each time a user logged in, so regardless of whether rules had been
previously added for a given user, 21 rules were added again at the next login — every time. For that reason, we did not limit ourselves to profiles that didn’t exist but rather domain users. (2) We were deploying this as a script to run hidden
in the background and so focused on logging details instead of displaying them on the screen.We did this with a simple CMD file that exports the list of registry entries based on the existence and contents of «LUOwn…» and then runs a powershell script to clean them up. Depending on how long it took, the SCCM job may fail due to
time exceeded this first time, but the script still finished running and could be run on a schedule within SCCM.@ECHO OFF REM Export the problem entries REM Note that these file paths are used as variables in fw_cleanup.ps1 so be sure to change them both places reg.exe query HKLMSYSTEMControlSet001ServicesSharedAccessParametersFirewallPolicyFirewallRules /f LUOwn=S-1-5-21 > c:tempfw_reg_rules.log reg.exe query HKLMSYSTEMControlSet001ServicesSharedAccessParametersFirewallPolicyRestrictedServicesConfigurableSystem /f LUOwn=S-1-5-21 > c:tempfw_reg_system.log REM Use powershell to parse the file and remove the registry keys PowerShell.exe -NoProfile -ExecutionPolicy Bypass -Command "& '%~dp0fw_cleanup.ps1'"
The SCCM program calls the CMD file above and runs it hidden whether or not a user is logged in, and this PS1 file is stored in the same directory:
# fw_cleanup.ps1 # Created - 2017-03-01 # Purpose - Clean up bad firewall rules in the registry based on the existence of LUOwn string in the definition # Populate date for logging $date = Get-Date -Format "yyyy-MM-dd_HHmmss" $systemFile = "C:TEMPfw_reg_system.log" $rulesFile = "C:TEMPfw_reg_rules.log" $log = "C:TEMPfw_cleanup" + $date + ".log" Try { "Running fw_cleanup.ps1 on " + $date | Out-File $log -append } Catch { Write-Warning "$_" } Try { "--------------------------------------------" | Out-File $log -append } Catch { Write-Warning "$_" } If(Test-Path $log) { # Process rules from HKLM:SYSTEMControlSet001ServicesSharedAccessParametersFirewallPolicyFirewallRules Try { "Beginning FirewallRules key processing" | Out-File $log -append } Catch { Write-Warning "$_" } Try { "--------------------------------------" | Out-File $log -append } Catch { Write-Warning "$_" } If(Test-Path $rulesFile) { foreach ($line in Get-Content $rulesFile) { If ($line -match "LUOwn") { # Grab just the GUID from the log file Try { $name = $line.Substring(4,38) } Catch { Write-Warning "$_" } If ($name) { Try { Remove-ItemProperty -Path "HKLM:SYSTEMControlSet001ServicesSharedAccessParametersFirewallPolicyFirewallRules" -Name $name $logentry = "Removed " + $name $logentry | Out-File $log -append } Catch { $logentry = $name + "$_" $logentry | Out-File $log -append } } } Else {} } $newRulesFile = "C:TEMPfw_reg_rules_" + $date + ".log" Try { Move-Item $rulesFile -Destination $newRulesFile } Catch { Write-Warning "$_" } } Else { Try { "No rules source file." | Out-File $log -append } Catch { Write-Warning "$_" } } # Process rules from HKLM:SYSTEMControlSet001ServicesSharedAccessParametersFirewallPolicyRestrictedServicesConfigurableSystem Try { "Beginning System key processing" | Out-File $log -append } Catch { Write-Warning "$_" } Try { "--------------------------------------" | Out-File $log -append } Catch { Write-Warning "$_" } If(Test-Path $systemFile) { foreach ($line in Get-Content $systemFile) { If ($line -match "LUOwn") { # Grab just the GUID from the log file Try { $name = $line.Substring(4,38) } Catch { Write-Warning "$_" } If ($name) { Try { Remove-ItemProperty -Path "HKLM:SYSTEMControlSet001ServicesSharedAccessParametersFirewallPolicyRestrictedServicesConfigurableSystem" -Name $name $logentry = "Removed " + $name $logentry | Out-File $log -append } Catch { $logentry = $name + "$_" $logentry | Out-File $log -append } } } Else {} } $newSystemFile = "C:TEMPfw_reg_system_" + $date + ".log" Try { Move-Item $systemFile -Destination $newSystemFile } Catch { Write-Warning "$_" } } Else { Try { "No system source file." | Out-File $log -append } Catch { Write-Warning "$_" } } } Else { Write-Warning "No log file." }
This leaves the NT AUTHORITY-based rules, which could be included by changing the search string in the CMD file from LUOwn=S-1-5-21 to LUOwn=S-1-5- instead. It also leaves the log files by date. We expect to clean up at a later time but wanted
to keep for reference for a bit.Good times! I hope this is helpful to someone, and thanks JS2010 for helping us get here!
-
So you make those input files with another script? I’m not using active directory, but it looks like the only difference is the active directory sid’s are more different than the local account sid’s. The computer shouldn’t make any new firewall
rules for a user unless the profile has been deleted. I have a few local accounts so I keep the firewall rules around for them (including System for configurableservicestore), but I don’t really know what they do; I guess allow Windows Apps full network
access. I did see a warning starting powershell when I deleted them from a local admin account.-
Edited by
JS2010
Thursday, March 9, 2017 6:49 PM
-
Edited by
-
Oh boy, you’re right! This is making by head hurt a little.
I thought we had a handle on the behavior, but you’re right that the rules don’t get added every time like we had assumed. We use a combination of local, roaming and mandatory profiles, and it seems it’s only the mandatory profiles that are adding
the rules each time. That makes some sense since changes to the profile are discarded on logout, but then the local profile stays for a week (in our environment) and the effect seems to be that those app rules are added each time for that subset of users.
Then, as you’ve mentioned, for local or roaming users it doesn’t seem to be a problem until the local profile is removed.So for our environment I think I get to add some more logic to my script to identify mandatory profiles and also use some of your script on identifying SIDs with no local profile. Just when I thought we were on the home stretch! Ha!
Thank you!
-
It seems a little better in Creator’s edition. Only 17 firewall rules get left behind after deleting a user’s profile.
function user2sid ($user)
{ Get-CimInstance win32_useraccount | where name -eq $user | select -exp sid }$usersid = user2sid ‘user’
Get-NetFirewallRule -owner $usersid | measureCount : 17
Get-CimInstance Win32_UserProfile | where localpath -eq ‘c:usersuser’ |
Remove-CimInstanceGet-NetFirewallRule -owner $usersid | measure
Count : 17
-
Edited by
JS2010
Wednesday, June 7, 2017 7:10 PM
-
Edited by
-
Having this problem as well, 5 RDSH servers and 1 of them had over 66000 rules.
Wasn’t even able to clean out «HKLMSYSTEMControlSet001ServicesSharedAccessParametersFirewallPolicyRestrictedServicesConfigurableSystem»
Powershell ran out of memory. Not even able to open that path in regedit, it just stops responding.
-
Have you tried something like this where you keep everything in the pipeline to save memory? (Remove-NetFirewallRule will take forever) (I’m passing the name property over the pipe) Even this might take hours. The newer win10 is better with this
problem (but not perfect).function sid2user($sid) { get-wmiobject -class win32_useraccount | where sid -eq $sid } $profiles = get-wmiobject -class win32_userprofile Get-NetFirewallRule -All -PolicyStore ConfigurableServiceStore | Where-Object { $profiles.sid -notcontains $_.owner -and $_.owner } | remove-itemproperty -path HKLM:SystemCurrentControlSetServicesSharedAccessParametersFirewallPolicyRestrictedServicesConfigurableSystem -verbose # -whatif
-
Edited by
JS2010
Tuesday, June 27, 2017 2:51 PM
-
Edited by
-
Im afraid that throws the same error.
Get-NetFirewallRule : There is not enough space available to complete this action.
/Fredrik
-
This is more from the Server 2016 point of view, but we seem to have found (on a fairly small sample set) that the new rules don’t get created if you’ve already gone ahead and prevented the related Desktop Experience «services» from being
spawned by new users.So that might be an approach to try. We get only one set related firewall rules created (when the server is built), and those are easy enough to manage.
Note that the first set of services we disable (in $deskexpSvcs) probably contains some stuff you’d want to keep on Win 10 workstations, so prune that section accordingly.
The reference document for the Server 2016 services and whether they’re «required» is here:
https://blogs.technet.microsoft.com/secguide/2017/05/29/guidance-on-disabling-system-services-on-windows-server-2016-with-desktop-experience/
#desktop experience services $deskexpSvcs = @( "QWAVE", "MapsBroker", "lfsvc", "wlidsvc", "WpnService", "AxInstSV", "lltdsvc", "bthserv", "dmwappushservice", "PhoneSvc", "NcbService", "PcaSvc", "RmSvc", "SensorDataService", "SensrSvc", "SensorService", "ShellHWDetection", "SSDPSRV", "WiaRpc", "TabletInputService", "upnphost", "WalletService", "Audiosrv", "AudioEndpointBuilder", "FrameServer", "stisvc", "icssvc", "XblAuthManager", "XblGameSave" ) #desktop experience services that can only be disabled in the reg key $deskexpReg = @( "CDPUserSvc", "PimIndexMaintenanceSvc", "NgcSvc", "NgcCtnrSvc", "OneSyncSvc", "UserDataSvc", "UnistoreSvc", "WpnUserService" ) $disablesvcs = $sysSvcs + $deskexpSvcs foreach ($svc in $disablesvcs) { get-service $svc |Set-Service -startuptype Disabled } foreach ($svc in $deskexpReg) { $SVCpath = "HKLM:SYSTEMCurrentControlSetServices" + $svc Set-ItemProperty -Path $SVCPath -Name Start -Value 4 -Type DWord } #remove Xbox scheduled tasks and folder Get-ScheduledTask | Where {$_.taskname -like "xbl*"} | unregister-ScheduledTask -confirm:$false $scheduleObject = New-Object -ComObject schedule.service $scheduleObject.connect() $rootFolder = $scheduleObject.GetFolder("") $rootFolder.DeleteFolder("MicrosoftXblGameSave",$null) #reboot
-
Edited by
TracMac
Monday, December 18, 2017 11:12 AM
-
Edited by
-
Old post, but as we ran into these issues as well:
at first I wrote a tool in .net that removes the bogus firewall rules, directly from registry. For the «HKLMSYSTEMCurrentControlSetServicesSharedAccessParametersFirewallPolicyRestrictedServicesAppIsoFirewallRules» I couldn’t find another
way to to it, as I can’t connect to that with the firewall APIs, opposed to the older location from pre 1703 I think it was.Anyway, my tool removes about 400.000 values in about 90 seconds. Caveat is that is does require a reboot to be effective. But again, as the AppIso rules can’t be removed through API, I don’t know of any other way.
After years Microsoft finally patches their f#ckup in November 2018:
https://support.microsoft.com/en-us/help/4467684/windows-10-update-kb4467684
- Addresses an issue that slows server performance or causes the server to stop responding because of numerous Windows firewall rules. To enable the changes, add a new registry key “DeleteUserAppContainersOnLogoff” (DWORD) on “HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesSharedAccessParametersFirewallPolicy”
using Regedit, and set it to 1.
Setting that value indeed cleans all auto-created rules, also the hidden ones af far as I can see, after logging off.
- Addresses an issue that slows server performance or causes the server to stop responding because of numerous Windows firewall rules. To enable the changes, add a new registry key “DeleteUserAppContainersOnLogoff” (DWORD) on “HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesSharedAccessParametersFirewallPolicy”
-
Thanks for the info. Here’s another area I’ve been cleaning up, to prevent high cpu from Appxsvc. I think «appuriverifierdaily» in Task Scheduler is related to this. Yes, there’s a registry key with literally the name «*».
$sids =Get-CimInstance win32_userprofile|
select-expand
sid
$keys
=ls
‘HKLM:SOFTWAREclasseslocal settingsSoftwareMicrosoftWindowsCurrentVersionAppModelDeploymentPackage**’
$DeleteList
=$keys |where {
$_.PSChildName
-ne‘AllUsers’
-and
-not ($_.PSChildName
-in
$sids
) }
$DeleteList
|rm -r-verbose# if this gets too numerous, search breaks
remove-item
HKLM:SYSTEMCurrentControlSetServicesSharedAccessParametersFirewallPolicyRestrictedServicesAppisoFirewallRulesNote also that deleting a lot of profiles at once will make Appxsvc use all the cpu of a machine.
-
Edited by
JS2010
Monday, June 3, 2019 5:14 PM
-
Edited by
-
Yeah, in my opinion 2008R2 was good, after that it becomes worse and worse. Of course some things have improved, but a lot of things are way worse than before. Who thought of putting a users customized start-menu (tiles) in AppDatalocal???
This is the list I have so far that is cleaned by my ‘logoff crapcleaner’ tool I wrote because Windows just leaves crap there. I’ve just added your AppModel line as well. What a trainwreck.
HKLMSOFTWAREMicrosoftWindowsCurrentVersionUFHARP
HKLMSOFTWAREMicrosoftUserManagerUsers
HKLMSOFTWAREMicrosoftWcmSvcwifinetworkmanagerfeatures<SID>
HKLMSOFTWAREMicrosoftWindows SearchGatherWindowsSystemIndexSites<SID>
HKLMSOFTWAREMicrosoftWindowsCurrentVersionAuthenticationCredential Providers{D6886603-9D2F-4EB2-B667-1971041FA96B}<SID>
HKLMSOFTWAREMicrosoftWindowsCurrentVersionSystemProtectedUserData<SID>
HKLMSOFTWAREMicrosoftWindowsCurrentVersionTouchKeyboardUsers<SID>
HKLMSOFTWAREWOW6432NodeMicrosoftWindows SearchGatherWindowsSystemIndexSites<SID>
HKLMSYSTEMCurrentControlSetServicesbamUserSettings<SID>
HKU.DEFAULTSoftwareMicrosoftIdentityCRLDeviceIdentitiesproduction<SID>
HKUS-1-5-18SoftwareMicrosoftIdentityCRLDeviceIdentitiesproduction<SID>
HKLMSOFTWAREMicrosoftWindowsCurrentVersionAuthenticationLogonUIUserTile
HKLMSOFTWAREMicrosoftWindowsCurrentVersionNetCachePurgeAtNextLogoff
HKLMSOFTWAREclasseslocal settingsSoftwareMicrosoftWindowsCurrentVersionAppModelDeploymentPackage**
- Remove From My Forums
-
Question
-
I have an start menu entry placed under this path on Win8 only.
HKLMSoftwareMicrosoftWindowsCurrentVersionUFHSCH
Does anyone have an idea what this registry meant for ?
Answers
-
Hi mkr23,
Can you please advise if you are creating a Metro App. The reason I ask is that Metro Style developers do not need write installers or uninstallers, as this is handled by the appx paclage process and not by the developer. Are you writing a Desktop app. If
so then you might be better posting to either to the desktop Development ForumsThanks
-
Edited by
Tuesday, July 24, 2012 9:15 PM
-
Proposed as answer by
mark_1h
Wednesday, July 25, 2012 11:27 PM -
Marked as answer by
Roberts_EModerator
Thursday, May 9, 2013 4:48 PM
-
Edited by
Кэш или таблица (Address Resolution Protocol, протокол определения адреса) хранит соответствия IP-адресов и аппаратных MAC-адресов устройств в локальной сети для быстрой установки соединения без повторного опроса компьютеров в сети.
Обычно, данные, хранящиеся в кэше, проблем не вызывают, но при возникновении ошибок при подключениях в локальной сети можно попробовать выполнить очистку кэша ARP на случай, если в нём хранятся неактуальные данные. Об очистке кэша ARP и пойдет речь далее в инструкции.
Очистка кэша ARP в командной строке
Базовый способ очистки таблицы ARP — использование командной строки. Используйте следующие шаги:
- Запустите командную строку от имени Администратора. В Windows 10 и Windows 11 для этого можно начать набирать «Командная строка» в поиске на панели задач, затем нажать правой кнопкой мыши по найденному результату и выбрать соответствующий пункт контекстного меню.
- Используйте одну из следующих команд для очистки кэша ARP:
netsh interface IP delete arpcache
или
arp -d
- Перезагрузите компьютер.
Кэш ARP очищен.
Просмотреть содержимое кэша ARP можно с помощью команды
arp -a
Учитывайте, что сразу после очистки в нем начнут появляться новые записи — пустой кэш вы, вероятнее всего, не увидите.
Существует возможность настроить время жизни кэша ARP, изменив значения параметров DWORD (по умолчанию могут отсутствовать):
- ArpCacheLife (120 секунд по умолчанию)
- ArpCacheMinReferencedLife (600 секунд по умолчанию)
в разделе реестра
HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesTcpipParameters
Время задается в секундах в десятичной системе счисления.
This blog post series has been inspired by a presentation at E2EVC on how to Optimize Logon Times to 3 seconds and fellow CTP Claudio Rodrigues who published a photo showing ControlUp Insights Logon Average of 4 seconds.
This 2nd post will show you how to Optimize the Operation System which will reduce the overall login times.
Previous Posts
Optimize Logon Times – Part 1: Citrix Director
In the last blog post we achieve real login times in Citrix Director and got an average login time of 6.10 seconds with 50 brand new profiles. I forgot to mention that the Operating System was already some optimized according to Citrix’s Windows 8 and Server 2012 Optimization Guide.
You might know there’s a lots of stuff added to the Run key that steals unnecessary memory and CPU resources. By removing unneeded software you’ll likely get a higher user density AND a faster login as a bonus.
HKLMSoftwareMicrosoftWindowsCurrentVersionRun |
- CtxStartMenuTaskbarUser – Windows 7 look on WS08R2 & XenApp 6.5
- StatusTray – Provisioning Services
- vDesk VDI – Personal vDisk
- DisableStatus – Slow logon with black screen (Citrix XenApp 7.6 Slow Logon)
The DisableStatus fix is an interesting one, it might or might not apply to your environment. I just added it to see if it had any effect on Citrix XenApp 7.9 which it didn’t. Now if you have read the comments from Helge Klein’s post linked above there’s now a new problem.
We have found one thing slowing down our logons on XA7.6 and Win2012R2 – both with and without FR3. Using Process Monitor we could see Windows Explorer was trying to delete registry entries in HKCU…UFHSHC.
We deleted all entries in this registry key for a user, then when the user next logged in the logon was around 30 seconds faster!
Again this didn’t have any big effect in my environment, but it’s a lab with temporary users. Take a look inside of the registry key and see if you have tons and tons of entries. There should only be x number equal to x number of shortcuts.
HKCUSoftwareMicrosoftWindowsCurrentVersionUFHSHC |
I did try to delete these entries at logon, but that broke my Turbo.net application shortcuts. So I found out that a better way was to add the location to the registry exclusion list in Citrix Profile Manager.
Now with brand new profiles the login time dropped from 6.10 to 5.60 seconds. An interesting observation is marked in red below. The first logons to each server is around 10-15 seconds and then it drops below 5 seconds (resources loaded into memory).
Running a new test with existing profiles give a login time of 4.28 seconds. A difference of 1.30 seconds between a new and existing profile.
As you remember from the last post Citrix Director shows a higher login time because of the way it starts the clock. There’s an excellent whitepaper from Goliath Technologies called The Complete Guide to Understanding the Citrix Logon Process for XenApp/XenDesktop which is HIGHLY recommended.
Now these 50 ms (new profile) probably seems like nothing, but you need to remember that I’m running on the worlds fastest consumer SSD storage. So where I gain 50 ms you’ll probably gain 10-15 seconds which makes a great deal. Please share you experience with these tunings in the comments below.