Take Ownership of Registry Subkey and Delete It via SYSTEM Account - powershell

I am deploying an update via WSUS to remove broken registry keys from Windows 10 systems running 1703 and 1709. The PowerShell code needs to open two registry keys, take ownership, set ownership to users, then delete them. The code below works when run from machines directly:
#Set our root registry key and new owner (Users)
$rootKey = "LocalMachine"
[System.Security.Principal.SecurityIdentifier]$sid = 'S-1-5-32-545'
#First key
$key = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileNotification\TDL"
#Take ownership and delete if it exists
if (Test-Path "HKLM:\$key") {
$regKey = [Microsoft.Win32.Registry]::$rootKey.OpenSubKey($key, 'ReadWriteSubTree', 'TakeOwnership')
$acl = New-Object System.Security.AccessControl.RegistrySecurity
$acl.SetOwner($sid)
$regKey.SetAccessControl($acl)
$acl.SetAccessRuleProtection($false, $false)
$regKey.SetAccessControl($acl)
Remove-Item -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileNotification\TDL" -Force -Recurse
} else{
Add-content $txtLogLocation "Key 1 does not exist."
}
However, I receive the following error when this code is run as the SYSTEM user (I deploy it via Windows Update, which runs this as SYSTEM):
Exception calling "OpenSubKey" with "3" argument(s): "Requested registry
access is not allowed."
At C:\Windows\TEMP\7zSAA99.tmp\1809ReadinessScript.ps1:224 char:2
+ $regKey = [Microsoft.Win32.Registry]::$rootKey.OpenSubKey($key, ' ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SecurityException
Exception calling "OpenSubKey" with "3" argument(s): "Requested registry
access is not allowed."
At C:\Windows\TEMP\7zSAA99.tmp\1809ReadinessScript.ps1:224 char:2
+ $regKey = [Microsoft.Win32.Registry]::$rootKey.OpenSubKey($key, ' ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SecurityException
Any thoughts on why this might be happening? Is it due to the SYSTEM user running it, or is it some odd PowerShell issue that requires a different method to handle opening registry keys?

I was able to work around this issue by using PowerShell to create a scheduled task that then runs the script that is downloaded locally to the machine. The task runs as the local user, which has the ability to open the subkey and thus change the permissions. SYSTEM for whatever reason did not have read access to this particular key.

Related

Powershell script throwing error while calling an API using ssl

We have a powershell script which is used to call an API by establishing connection over SSL. The certificates are placed along powershell script to be used by it. And the password is mentioned in an ini file which script reads. It was working fine earlier but suddenly it has started giving below error:
Exception calling "Import" with "3" argument(s): "The specified network password is not correct.
"
At C:\Users\Administrator\Desktop\NewInstallIssue\Download\win\installCDWindows.ps1:70 char:3
+ $cert.Import($CertificatePath, $KeyStore_Password ,'DefaultKeySet')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : CryptographicException
The part of powershell script throwing this error is:
$cert= New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$CertificatePath = Join-Path -Path $PSScriptRoot -ChildPath 'cdCert.pfx'
$cert.Import($CertificatePath, $KeyStore_Password ,'DefaultKeySet')
$KeyStore_Password contains correct password as I tested what is stored in this variable just before $cert.Import using echo.

powershell Command Works When run alone, but note when scripted

I am working on a deployment script for some software, and my script is working on probably 90% of the machines it runs on, but on the other 10%, I get a failure in the download portion. Here is what I have:
$tls = "Tls";
$Token = "#ZorusKey#";
[System.Net.ServicePointManager]::SecurityProtocol = $tls;
$source = <Source>
$destination = "C:\installers\ZorusInstaller.exe";
$WebClient = New-Object System.Net.WebClient
$WebClient.DownloadFile($source, $destination)
I have created the C:\installers folder on all target machines, so I don't think that's the problem. When run as a script, I get the following exception:
Exception calling "DownloadFile" with "2" argument(s): "An exception occurred during a WebClient request."
At C:\Windows\system32\config\systemprofile\AppData\Local\f1e96243cb9c4ef0b0336a152ed8827f.ps1:8 char:1
+ $WebClient.DownloadFile($source, $destination)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : WebException
Which then causes the following steps to fail, as the downloaded file doesn't exist.
I have also taken the step on several of the failing machines of running each line of the script above one at a time (copied / pasted from the same Powershell ISE window) and the download works without issue. looking for a possible reason / resolution.
Thanks in advance.

Script Only Runns Sucessfully 50-60% of the time

I'm sending a zip and the powershell script to computers in our organisation through our management software and then executing the powershell script through command prompt. The script unzips the folder, installs a program and adds some registry keys to the registry.
If the machine doesnt say that a policy is preventing execution of the script, it runs as expected, the program is installed and the registry keys are imported. But if it does give the warning and I set the policy to unrestricted I get the below error error. I am on Windows 8.1 and using Powershell 4.0
Id not be found.
At C:\Temp\tps1.ps1:5 char:9
+ Add-Type <<<< -assembly "system.io.compression.filesystem"
+ CategoryInfo : ObjectNotFound: (system.io.compression.filesyste
m:String) [Add-Type], Exception
+ FullyQualifiedErrorId : ASSEMBLY_NOT_FOUND,Microsoft.PowerShell.Commands
.AddTypeCommand
Add-Type : Cannot add type. One or more required assemblies are missing.
At C:\Temp\tps1.ps1:5 char:9
+ Add-Type <<<< -assembly "system.io.compression.filesystem"
+ CategoryInfo : InvalidData: (:) [Add-Type], InvalidOperationExc
eption
+ FullyQualifiedErrorId : ASSEMBLY_LOAD_ERRORS,Microsoft.PowerShell.Comman
ds.AddTypeCommand
Unable to find type [io.compression.zipfile]: make sure that the assembly conta ining this type is loaded.
At C:\Temp\tps1.ps1:7 char:25
+ [io.compression.zipfile] <<<< ::ExtractToDirectory($BackUpPath, $destination) + CategoryInfo : InvalidOperation: (io.compression.zipfile:String
) [], RuntimeException
+ FullyQualifiedErrorId : TypeNotFound
anyone have any ideas?
on systems where .NET 4.5 is not installed, use:
$BackUpPath = "C:\Temp\Install.zip"
$Destination = "C:\Temp"
$shell_app=new-object -com shell.application
$zip_file = $shell_app.namespace($BackUpPath )
$destination = $shell_app.namespace($Destination )
$destination.Copyhere($zip_file.items(),0x4)
on systems with.NET 4.5 use:
Add-Type -assembly "system.io.compression.filesystem"
[io.compression.zipfile]::ExtractToDirectory($BackUpPath, $destination)
A script on technet combines the above 2 methods.
On PowerShell V5 , this is much simplified:
Expand-Archive $BackUpPath -destination $Destination
there are other ways to unzip files using 3rd party libraries such as 7-zip, etc but that creates a dependency.
Note: Powershell execution policies can be set using group policy. see link here

Remote registry query

I am trying to get a registry value from a remote machine but everything I have tried did not work.
Both machines are running windows 7 x64, they are on the same domain, firewall off, powershell 4.0
when I run :
$reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", "APPS-EUAUTO1")
$key = $reg.OpenSubkey('SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion')
Write-Host $key.GetValue('InstallDate')
i get
Exception calling "OpenRemoteBaseKey" with "2" argument(s): "The network path was not found.
"
At C:\Users\User\Desktop\test.ps1:1 char:1
+ $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("LocalMachine", "APPS-EU ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : IOException
I know nothing of .Net and I have only played with PowerShell for the last month.
I have also tried the module PSRemoteRegistry and when I am using Get-RegValue I get the same error message (I think it is using the same thing)
Assuming you can ping APPS-EUAUTO1(and it resolves to correct IP) and firewall is off.. make sure Remote Registry service is running on your APPS-EUAUTO1

Remote Powershell Access denied for certain dll's execution for Sharepoint 2013

I am attempting to automate a sharepoint 2013 deployment via remote powershell from the build server. Everything executes as expected except when having anything to do with some class in sharepoint dll's such as (Microsoft.SharePoint.Publishing, Microsoft.SharePoint.Publishing.Navigation.WebNavigationSettings)
If I run the same script locally under the same credentials it runs fine.
I have considered the below:
The user has full admin right on both machines
Disabled UAC on the remote server
Followed the required Remote Powershell steps in thig post (http://social.technet.microsoft.com/Forums/sharepoint/en-US/09b60466-5432-48c9-aedd-1af343e957de/user-cannot-be-found-when-using-invokecommand-newspsite-on-sharepoint)
I set powershell to run as admin by defualt via the registry (New-Item -Path "Registry::HKEY_CLASSES_ROOT\Microsoft.PowershellScript.1\Shell\runas\command" -Force -Name '' -Value '"c:\windows\system32\windowspowershell\v1.0\powershell.exe" -noexit "%1"')
Script Code:
#Set the radio buttons value
$settings = New-Object Microsoft.SharePoint.Publishing.Navigation.WebNavigationSettings (,$rootWeb)
$settings.GlobalNavigation.Source = [Microsoft.SharePoint.Publishing.Navigation.StandardNavigationSource]::PortalProvider
#Set the radio buttons value
$settings.CurrentNavigation.Source = [Microsoft.SharePoint.Publishing.Navigation.StandardNavigationSource]::PortalProvider
write-host "I am here.........................."
$settings.Update()
#Set the Publishing Web
$SPPubWeb = [Microsoft.SharePoint.Publishing.PublishingWeb]::GetPublishingWeb($rootWeb)
#Global Navigation Settings
$SPPubWeb.Navigation.InheritGlobal = $false
$SPPubWeb.Navigation.GlobalIncludePages = $false
The Remote Powershell output is as below:
I am here..........................
Exception calling "Update" with "0" argument(s): "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : UnauthorizedAccessException
+ PSComputerName : Contoso-DEVSP
Exception setting "GlobalIncludePages": "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
+ PSComputerName : Contoso-DEVSP
Many thanks in advance
You need to check CredSSP authentication. Remote PowerShell execution with SharePoint fails as the second hop translates the credentials to system credentials. If the task involves querying or updating DB server, it will fail as SYSTEM account will not have access the remote PowerShell on SQL Server. You need to enable CredSSP.
Check this blog post I wrote a while ago. This is not specific to SharePoint but it should apply to your scenario as well.
http://www.ravichaganti.com/blog/?p=1230