Find and delete/change registry entry with powershell - powershell

I can get registry elements like this:
PS> $Registry_Key = "HKLM:\SOFTWARE\Wow6432Node\Lenovo\Access Connections\Locations\*\*\*"
PS> Get-ItemProperty -path $Registry_Key -name m_bSetBrowserPxySettings -ErrorAction SilentlyContinue
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Lenovo\Access Connections\Locations\BMZ-GmbH\AdptList\Adpt00
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Lenovo\Access Connections\Locations\BMZ-GmbH\AdptList
PSChildName : Adpt00
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
m_bSetBrowserPxySettings : 1
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Lenovo\Access Connections\Locations\BMZ-GmbH\AdptList\Adpt01
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Lenovo\Access Connections\Locations\BMZ-GmbH\AdptList
PSChildName : Adpt01
PSDrive : HKLM
PSProvider : Microsoft.PowerShell.Core\Registry
m_bSetBrowserPxySettings : 1
But now I want to delete m_bSetBrowserPxySettings completely, or change the value to "0" for every match in this search. Change or delete doesn't matter. What do I have to add to my script to achieve this?

You can do it as follows:
$Registry_Key = "HKLM:\SOFTWARE\Wow6432Node\Lenovo\Access Connections\Locations\*\*\*"
Get-ItemProperty -path $Registry_Key -name m_bSetBrowserPxySettings -ErrorAction SilentlyContinue | % { Set-ItemProperty -path $_.PSPath -name m_bSetBrowserPxySettings "0" }
You need pipe the Get-ItemProperty command to:
% { Set-ItemProperty -path $_.PSPath -name m_bSetBrowserPxySettings "0" }
% represents the ForEach-Object cmdlet. What it will do is iterate over each item in the collection you get out of the Get-ItemProperty command. $_ represents the object in the pipeline, so this will change to the new item on each iteration.
$_.PSPath is the path to the registry key of the item. You can see this printed in the table in your question. You can use this value to pass to Set-ItemProperty along with your name and then set the value to whatever you want.
If you wanted to remove the item altogether, pipe to the following instead:
% { Remove-ItemProperty -path $_.PSPath -name m_bSetBrowserPxySettings }

Rather than working with the path all the time you can just work on the item itself:
$Registry_Key = "HKLM:\SOFTWARE\Wow6432Node\Lenovo\Access Connections\Locations\*\*\*"
$item = Get-Item $Registry_Key
$item | Get-ItemProperty -name m_bSetBrowserPxySettings -ErrorAction SilentlyContinue
Then to set it to 0:
$item | Set-ItemProperty -name m_bSetBrowserPxySettings "0"
Or to delete it:
$item | Remove-ItemProperty -name m_bSetBrowserPxySettings

Related

How do I add a variable into a specific registry key path via Powershell?

I currently have a script which looks for a specific program to exist in Add/Remove programs and I would like to add the "Dell Command" into registry to confirm.
#Find the Dell Command Update in Add/Remove Programs
Get-ChildItem HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall |
% {Get-ItemProperty $_.PsPath} |
where {$_.Displayname -match "Dell Command"} |
sort Displayname | select DisplayName
If you would like to create a key based on the value returned from your search, you can do the following:
$dellCommand = (Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*" | Where-Object -Property "DisplayName" -Match "Dell Command").DisplayName
$regKeyPath = "HKLM:\SOFTWARE\$dellCommand"
if (-not (Test-Path -Path $regKeyPath)) {
Write-Output -InputObject "$regKeyPath doesn't exist. Creating key."
$newKey = New-Item -Path $regKeyPath -Force #Create the key if it doesn't exist.
#Add Property values to the key
#$newKey | New-ItemProperty -Name "blah" -Value "valuevalue" -PropertyType "type" -Force
}
else {
Write-Output -InputObject "Key already exists: [$dellCommand]."
}
Here, you can test to see if the key already exists and create it if it doesn't. Since New-Item produces an output of the object, you can use that to pipe into New-ItemProperty if needed to add properties to the key (demonstrated above).

One-liner to find a registry key and delete parent works but returns an error

I am using a one liner to find a registry key based on a value then delete it's parent. The one liner produces an error but if I separate the search result into a variable and run remove-item there is no error. I'd like to find out what causes this and if I should I be worried?
Produces an error:
Get-ChildItem -path HKLM:\SOFTWARE\Classes\Installer\Products -Recurse -ErrorAction Stop | Get-ItemProperty -Name "PackageName" -ErrorAction SilentlyContinue| where { $_.PackageName -cmatch "BigFixAgent\.msi" } | Select-Object -ExpandProperty PSParentPath | Remove-Item -Recurse -confirm
Get-ChildItem : The registry key at the specified path does not exist.
At line:1 char:1
+ Get-ChildItem -path HKLM:\SOFTWARE\Classes\Installer\Products -Recurs ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (HKEY_LOCAL_MACH...4D34\SourceList:String) [Get-ChildItem],
ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.GetChildItemCommand
Produces No Errors:
$offending_key= Get-ChildItem -path HKLM:\SOFTWARE\Classes\Installer\Products -Recurse -ErrorAction Stop | Get-ItemProperty -Name "PackageName" -ErrorAction SilentlyContinue| where { $_.PackageName -cmatch "BigFixAgent\.msi" } | Select-Object -ExpandProperty PSParentPath
Remove-Item -Recurse $offending_key -confirm
That's because it is iterating recursively through the registry tree, and you deleted part of that tree in the middle of the iteration. You could put parenthesis around everything but the last part, so that it finishes iteration first, or you could put the last part in a ForEach-Object loop, and add a break after it so once that key is found it removes it and stops looking.
Complete Get-ChildItem iteration before deleting:
(Get-ChildItem -path HKLM:\SOFTWARE\Classes\Installer\Products -Recurse -ErrorAction Stop | Get-ItemProperty -Name "PackageName" -ErrorAction SilentlyContinue| where { $_.PackageName -cmatch "BigFixAgent\.msi" } | Select-Object -ExpandProperty PSParentPath) | Remove-Item -Recurse -confirm
Stop after finding the first matching key:
Get-ChildItem -path HKLM:\SOFTWARE\Classes\Installer\Products -Recurse -ErrorAction Stop | Get-ItemProperty -Name "PackageName" -ErrorAction SilentlyContinue| where { $_.PackageName -cmatch "BigFixAgent\.msi" } | Select-Object -ExpandProperty PSParentPath | ForEach-Object {$_ | Remove-Item -Recurse -confirm; break}

Get regkey based on search, then add new entry to that key

I am trying to search the HKLM hive for the key driverdesc that contains the value -like "*Ethernet*"
I can retrieve all the keys with driverdesc, however I cannot filter for the one containing Ethernet and then add the REG_DWORD 'PNPCapabilities' to that key.
Here's how I am searching the registry:
Get-ChildItem "HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}" -Recurse -ErrorAction SilentlyContinue | foreach {$_.GetValue("Driverdesc")} | Out-String $Items
$items
You could use my function Search-Registry for this.
Search the registry like this:
Search-Registry -KeyPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}' -Pattern "*Ethernet*" -SearchPropertyValue -Recurse
This will return an array of objects with the following properties (example):
ComputerName : YOURMACHINE
Hive : LocalMachine
HiveName : HKEY_LOCAL_MACHINE
HiveShortName : HKLM
Path : HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\0007
SubKey : SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}\0007
ItemType : RegistryProperty
DataType : REG_SZ
ValueKind : String
PropertyName : DriverDesc
PropertyValue : Realtek RTL8168D/8111D Family PCI-E Gigabit Ethernet NIC (NDIS 6.20)
PropertyValueRaw : Realtek RTL8168D/8111D Family PCI-E Gigabit Ethernet NIC (NDIS 6.20)
Using these properties (most likely Path) it should be easy enough to add a new DWord value. So in your case:
$value = 1234
$items = Search-Registry -KeyPath 'HKLM:\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002bE10318}' -Pattern "*Ethernet*" -SearchPropertyValue -Recurse -Verbose
$items | Where-Object { $_.PropertyName -eq 'DriverDesc' } | ForEach-Object {
# New-ItemProperty either wants the shortpath notation 'HKLM:\path'
# or uses the 'Registry::HKEY_LOCAL_MACHINE\path' notation
$path = $_.HiveShortName + ':\' + $_.SubKey
New-ItemProperty -Path $path -Name 'PNPCapabilities' -Value $value -PropertyType DWORD -Force| Out-Null
}

Powershell File Length Exception Issue

I have been trying to run this script that captures all the files / folders within a share directory and passes it back to splunk. However the script is giving PathTooLongException 's even though the longest path i can find comes in at 197 characters.
I have tried mapping a share as a folder called z on the root of the C drive which doesnt help at all. Can someone shed some light on how to get around this or what is causing the errors?
param (
[string]$directory = "C:\Windows\Logs"
)
$errorCount = 0
$OutputList = #()
$directoryLink = 'c:\z'
#set up symbolic link
cmd /c mklink /d $directoryLink $directory
try
{
$colItems = (Get-ChildItem -Path $directoryLink -Recurse | Sort-Object)
}
catch
{
$errorCount += 1
}
foreach ($i in $colItems)
{
try
{
$subFolderItems = (Get-Item $i.FullName | Measure-Object -property
length -sum -ErrorAction SilentlyContinue)
$acl=$i.GetAccessControl()
$SizeValue= [Math]::Round(($subFolderItems.sum / 1MB),3)
$SplunkFileList = New-Object PSObject
$SplunkFileList | Add-Member -type NoteProperty -name Filename -Value $i.FullName
$SplunkFileList | Add-Member -type NoteProperty -name SizeMb -Value $SizeValue
$SplunkFileList | Add-Member -type NoteProperty -name LastAccess -Value $i.LastAccessTime
$SplunkFileList | Add-Member -type NoteProperty -name Owner -Value $acl.Owner
if ($i.PSIsContainer)
{
$SplunkFileList | Add-Member -type NoteProperty -name Type -Value "D"
}
else
{
$SplunkFileList | Add-Member -type NoteProperty -name Type -Value "F"
}
$OutputList += $SplunkFileList
}
catch [System.IO.IOExeception]
{
Write-Host 'An Exception was caught.'
Write-Host "Exception : $($_.Exception.GetType().FullName)"
$errorCount += 1
}
}
$OutputList | Select-Object Filename,SizeMb,LastAccess,Owner,Type | Format-
List
If you're using a modern version of Powershell (v5.1+ I think) you can get to the paths longer than 260 characters using the unicode version of Windows API.
To do this you prefix the path with \\?\ eg:
Get-ChildItem -LiteralPath '\\?\C:\Windows\Logs' -Recurse
Note: LiteralPath instead of Path
If you want to use a UNC path (\\server\C$\folder) the syntax is slightly different:
Get-ChildItem -LiteralPath '\\?\UNC\server\C$\folder' -Recurse

Powershell not creating registry key when script is run

I am currently creating a powershell script in which the technicians can run to help apply various registry edits to create certain PCs which have automatic logins. However, whenever I run my script the powershell has no issue when changing values with pre-existing keys, yet it will not create keys when using the "new-item" command. I was wondering whether anyone would have any idea as to why this would not create the registry key given that I receive no errors when run.
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" –Name AutoAdminLogon -Value 1
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultUserName -Value domain\TEST
Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name DefaultPassword -Value TEST123
Test-Path –Path "HKLM:\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\Winlogon\ForceAutoLogon"
if ( -Not (Test-Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"))
{
New-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" -Name ForceAutoLogon -Value 1
}
Test-Path is not designed for registy values. What you can do it use a Try/Catch block. You also need to Get/Set the itemPropery.
$Path = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon"
Try {
Get-ItemProperty -Path $Path | Select-Object -ExpandProperty ForceAutoLogon -ErrorAction Stop | Out-Null
Set-ItemProperty -Path $Path -Name ForceAutoLogon -Value 1
} Catch {
New-ItemProperty -Path $Path -Name ForceAutoLogon -Value 1
}
If the Get-ItemProperty fails the the key must not exist. Then we can create it! If Get-ItemProperty succeeds then we can ensure the value is set properly. I might be using the registry keywords wrong but let the code speak for itself.