DefaultMediaCost Registry Entry
We have 4GLTE cards in our laptops and have unlimited data (Public Safety plans), so we try to set all of our laptops to "unmetered". Thru the GUI it does not work and requires a change to the registry: HKLM\Software\Microsoft\Windows NT\NetworkList\DefaultMediaCost\. The default owner is "TrustedInstallter" and users have read-only. We must change the owner and permissions before changing values.
Now, it's easy to change a reg key with Deploy...normally. However...whenever Windows 10 does an update to a new realease (21H1) the owner of the key gets changed back to "TrustedInstaller", all the permissions go back to default, and the values go back to metered (1).
I'm looking for a solution that will change those values if:
The value is set (1)
Then, change owner
Change permissions
Change the value to (2)
Thoughts?
Comments
# Tool to enumerate a list of computers stored in hosts.txt and update the Cellular registry keys.
# Must be run with an account that has administrator permissions on the remote machines.
#
#
# Script does the following:
# Takes ownership of HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\DefaultMediaCost
# Gives the local administrators group FullControl permissions to the key
# Sets the 3g and 4g to value of 1
# Reverts local administrators group back to ReadKey to the key
# Sets ownership of the key back to TrustedInstaller
#
#
# I borrowed a portion of the code from https://stackoverflow.com/questions/12044432/how-do-i-take-ownership-of-a-registry-key-via-powershell
# I chopped out pieces that I needed and added a bit of my own.
#
# Junk pieced together by:
# Rich Engel
# richengel.junk@gmail.com
#
# Use at your own risk.
# I hope someone finds some benefit to this.
try {
$computer = Get-Content .\hosts.txt -ErrorAction Stop
} catch {
[System.Windows.MessageBox]::Show('hosts.txt file not found. Terminating')
exit
}
Foreach ($comp in $computer){
Invoke-Command -ComputerName $comp -ScriptBlock {
function Take-Permissions {
# Function found on internet and trimmed down for this script. Original Source....
# Developed for PowerShell v4.0
# Required Admin privileges
# Links:
# http://shrekpoint.blogspot.ru/2012/08/taking-ownership-of-dcom-registry.html
# http://www.remkoweijnen.nl/blog/2012/01/16/take-ownership-of-a-registry-key-in-powershell/
# https://powertoe.wordpress.com/2010/08/28/controlling-registry-acl-permissions-with-powershell/
param($rootKey, $key, [System.Security.Principal.SecurityIdentifier]$sid = 'S-1-5-32-545', $recurse = $false)
switch -regex ($rootKey) {
'HKCU|HKEY_CURRENT_USER' { $rootKey = 'CurrentUser' }
'HKLM|HKEY_LOCAL_MACHINE' { $rootKey = 'LocalMachine' }
'HKCR|HKEY_CLASSES_ROOT' { $rootKey = 'ClassesRoot' }
'HKCC|HKEY_CURRENT_CONFIG' { $rootKey = 'CurrentConfig' }
'HKU|HKEY_USERS' { $rootKey = 'Users' }
}
### Step 1 - escalate current process's privilege
# get SeTakeOwnership, SeBackup and SeRestore privileges before executes next lines, script needs Admin privilege
$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)
}
function Take-KeyPermissions {
# Function found on internet and trimmed down for this script
param($rootKey, $key, $sid, $recurse, $recurseLevel = 0)
### Step 2 - get ownerships of key - it works only for current key
$regKey = [Microsoft.Win32.Registry]::$rootKey.OpenSubKey($key, 'ReadWriteSubTree', 'TakeOwnership')
$acl = New-Object System.Security.AccessControl.RegistrySecurity
$acl.SetOwner($sid)
$regKey.SetAccessControl($acl)
}
Take-KeyPermissions $rootKey $key $sid $recurse
}
Function Set-Permissions {
# function to set permissions on key (My addtion)
param([System.Security.Principal.SecurityIdentifier]$sidXX = 'S-1-5-32-544', $access)
$key = [Microsoft.Win32.Registry]::localmachine.opensubkey("SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\DefaultMediaCost",[Microsoft.Win32.RegistryKeyPermissionCheck]::ReadWriteSubTree,[System.Security.AccessControl.RegistryRights]::ChangePermissions)
$aclXX = $key.getaccesscontrol()
$ruleXX = New-Object System.Security.AccessControl.RegistryAccessRule ($sidXX,$access,"ContainerInherit", "None", "Allow")
$aclXX.setaccessrule($ruleXX)
$key.setaccesscontrol($aclXX)
}
#_________________________________________________________________________________________________________
#_________________________________________________________________________________________________________
#
# Main code
#
# S-1-5-32-544 ... local administrators group
# S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464 ... trusted installer
# Other well-known-sids: https://docs.microsoft.com/en-us/windows/win32/secauthz/well-known-sids
# Example: S-1-5-32-545 ... local users group
# Local Administrators takes ownership of key
Take-Permissions 'HKLM' 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\DefaultMediaCost' 'S-1-5-32-544'
# Local Administrators granted Full Control
# Note: You can use a different SID if desired
Set-Permissions 'S-1-5-32-544' 'FullControl'
# Set registry values to 1
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\DefaultMediaCost' -Name '3G' -Value '1' -PropertyType DWORD -Force
New-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\DefaultMediaCost' -Name '4G' -Value '1' -PropertyType DWORD -Force
# Local Adminstrators reverted to Read Only
# Note: Optional you don't need to remove the permission if you want users to change the values on their own.
Set-Permissions 'S-1-5-32-544' 'ReadKey'
# TrustedInstaller takes ownership of key
Take-Permissions 'HKLM' 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\DefaultMediaCost' 'S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464'
}
}