Managing Registry With PowerShell? - powershell

I'm creating a reg key in HKCU which I want to audit with other scripts. I want to ensure that all other users (to include other admins) are unable to edit this key.
I'm looking to write a quick blerb that wipes the current permissions or sets them all to Deny and then adds full control to my user. I believe I have to break Inheriting too, which I'm not sure how to do. If possible I'd like to do all of this through PowerShell, although I'm curious how that would work with GPO as well. This is what I have so far.
# Set Validation Key
Push-Location
Set-Location HKCU:
Test-Path .\System\Security
New-Item -Path .\System -Name Security
Set-Item -Path HKCU:\System\Security -Value "Yes"
Rename-ItemProperty -Path HKCU:\System\Security -Name '(Default)' -NewName 'Validated'
Pop-Location
# Manage Key Permissions
$Acl = Get-Acl "HKCU:\System\Security"
$Acl.RemoveAccessRuleAll()
$Ar = New-Object System.Security.AccessControl.RegistryAccessRule('username', 'fullcontrol', 'allow')
$Acl.SetAccessrule($Ar)

Related

The requested registry access is invalid

I'm a learning System engineer and I have to Script a PowerShell Script who simply creates a Registry Key and a Value in it. I can't get it right, there is always this weird error popping up. Likewise, I already tried running it as an Administrator. Please Help!
Translation of the Error.
“The requested registry access is invalid.”
Script:
$regkey="HKEY_LOCAL_MACHINE\Software\Microsoft\Windows Defender\Reporting"
$regparam="DisableEnhancedNotifications"
cd HKLM:\
New-ItemProperty -Path "$regkey" -Name "$regparam" -Value "test" -PropertyType "String"
Thanks!
$regkey='HKLM:\SOFTWARE\Microsoft\Windows Defender\Reporting'
$regparam='DisableEnhancedNotifications'
# create key
New-Item -Path $regkey -Force
# create entry
New-ItemProperty -Path $regkey -Name $regparam -PropertyType String -Value 'test' -Force
more examples: Working with Registry Entries (learn.microsoft.com)

Create a powershell script to place a custom word template in the templates folder

I want to place a word template, template.dotm into the Word custom templates folder.
Using Office 365, latest version of Word. Windows 10. Apologies if my terminology is incorrect, still a powershell/programming novice.
This folder doesn't exist by default, and the directory Word looks for default templates in doesn't exist by default either. If a user has created a template, then it will create an expanding string named PersonalTemplates at the following registry key: HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Word\Options, with the value being the directory they've elected as their default custom templates directory.
I want to make a script which:
Checks for presence of PersonalTemplates. If present, and value is not null, store as $regvalue.
If not present, or value is null, create expanding string with the following value $newreg at HKEY_CURRENT_USER\SOFTWARE\Microsoft\Office\16.0\Word\Options.
Then copy template.dotm into the $regvalue or $newreg. Powershell will be run from the same directory as the template.dotm is stored in.
I've got a bunch of snippets which do some of the principle operations, though I can't work out how to tie them together, and am missing some bits which I just can't work out:
Copy the template to the destination
ForEach ($user in (Get-ChildItem "C:\Users" -Exclude Public)) {
New-Item -ItemType Directory -Force -Path "C:\Users$($user.Name)\Documents\Custom Office Templates"
Copy-Item template.dotm -Destination "C:\Users$($user.Name)\Documents\Custom Office Templates"
Create registry key with value
Set-Location -Path
'HKCU:\SOFTWARE\Microsoft\Office\16.0\Word\Options'
New-ItemProperty -Path
'HKCU:\SOFTWARE\Microsoft\Office\16.0\Word\Options' -Name
'PersonalTemplates' -Value "C:\Users$($user.Name)\Documents\Custom
Office Templates" -PropertyType ExpandString -Force }
Get regvalue
$regvalue = (Get-ItemPropertyValue
'HKCU:\SOFTWARE\Microsoft\Office\16.0\Word\Options'
'PersonalTemplates')
I have put together your code snippets in order, also corrected the logic for checking if the Registry key is present or not.
ForEach ($user in (Get-ChildItem "C:\Users" -Exclude Public))
{
$location = "C:\Users\$($user.Name)\Documents\Custom Office Templates"
$IsPresent = Get-ItemProperty 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Word\Options' | ForEach-Object {If($_ -like '*PersonalTemplates*'){ Return 'True' }}
if(-Not($IsPresent -eq 'True'))
{
New-ItemProperty -Path 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Word\Options' -Name 'PersonalTemplates' -Value $location -PropertyType ExpandString -Force \\Not tested
New-Item -ItemType Directory -Force -Path $location
}
$existingValue= Get-ItemPropertyValue -Path 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Word\Options' -Name 'PersonalTemplates'
if([string]::IsNullOrWhiteSpace($existingValue)){
Set-ItemProperty -Path 'HKCU:\SOFTWARE\Microsoft\Office\16.0\Word\Options' -Name 'PersonalTemplates' -Value $location
}
else{
$location=$existingValue
if(!(test-path $existingValue))
{
New-Item -ItemType Directory -Force -Path $existingValue
}
}
Copy-Item template.dotm -Destination $location
}
I have not tested the creation of registry key as I am on my work laptop, so assuming that line of code works.
Also, question for you: With this approach wouldn't the registry entry have the single value that of the first user folder, you may have to look into the logic? I feel you may have to run this script for each user after they login using $env:Username instead of looping through the user folder. But I could be wrong, there may be other who could suggest better.

Home Drive Creation Issue

I have PowerShell a script to create a new user's home drive and I am using below command:
Set-ADUser $User -HomeDrive $driveLetter -HomeDirectory $fullPath
It's creating the home drive for the user but the user isn't able to access it.
One more thing, I can copying the created home drive manually from AD console and again pasting it and clicking on apply then it works fine.
Set-ADUser will only modify the user object in ActiveDirectory; security permissions on the folder itself is an additional step.
FileSystemRights Enumeration: MSDN
It is not sufficient to simply use Set-ADUser, expecting full end to end creation of a fully functioning home directory; we must set permissions on the folder in question, including any inheritance flags.
There's a few steps to accomplish this, but simply stated:
We need to get the current access control list (ACL)
We need to add our desired permissions to said ACL
We need to write the new ACL, combining both the pre-existing and new permissions.
As you may have guessed:
Get-ACL
Set-ACL
We can so something like this:
Set-ADUser $User -HomeDrive $driveLetter -HomeDirectory $fullPath -ea Stop
$homeShare = New-Item -path $fullPath -ItemType Directory -force -ea Stop
$acl = Get-Acl $homeShare
$FileSystemRights = [System.Security.AccessControl.FileSystemRights]"Modify"
$AccessControlType = [System.Security.AccessControl.AccessControlType]::Allow
$InheritanceFlags = [System.Security.AccessControl.InheritanceFlags]"ContainerInherit, ObjectInherit"
$PropagationFlags = [System.Security.AccessControl.PropagationFlags]"InheritOnly"
$AccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule ($User.SID, $FileSystemRights, $InheritanceFlags, $PropagationFlags, $AccessControlType)
$acl.AddAccessRule($AccessRule)
Set-Acl -Path $homeShare -AclObject $acl -ea Stop
If you're feeling creative, you can also combine some of the flags into an array:
$InheritanceFlag = #('ContainerInherit','ObjectInherit')
Please note this code is NOT tested and to validate before executing in any environment.

Substitute icacls.exe with powershell

I want to replace the following CMD command with a Powershell command:
Icacls.exe "%SystemDrive%\xxx" /grant *S-X-X-XX-XXX:(CI)(OI)(F) /t /c
I also know how to do this with Icacls, but I think there is a nicer way to do it with the PowerShell.
I would be happy if someone could help me in this regard. :-)
Thanks.
The built-in help files, provide you the guidance for this.
Set-Acl Changes the security descriptor of a specified item, such
as a file or a registry key.
# Get specifics for a module, cmdlet, or function
(Get-Command -Name Get-Acl).Parameters
(Get-Command -Name Get-Acl).Parameters.Keys
<#
# Results
Path
InputObject
LiteralPath
Audit
AllCentralAccessPolicies
Filter
Include
Exclude
...
#>
Get-help -Name Get-Acl -Examples
<#
# Results
Get-Acl C:\Windows
Get-Acl -Path "C:\Windows\k*.log" |
Format-List -Property PSPath, Sddl
Get-Acl -Path "C:/Windows/k*.log" -Audit |
ForEach-Object { $_.Audit.Count }
Get-Acl -Path "HKLM:\System\CurrentControlSet\Control" |
Format-List
Get-Acl -InputObject (Get-StorageSubsystem -Name S087)
#>
Get-help -Name Get-Acl -Full
Get-help -Name Get-Acl -Online
(Get-Command -Name Set-Acl).Parameters
(Get-Command -Name Set-Acl).Parameters.Keys
<#
# Results
Path
InputObject
LiteralPath
AclObject
CentralAccessPolicy
ClearCentralAccessPolicy
Passthru
Filter
Include
Exclude
...
#>
Get-help -Name Set-Acl -Examples
<#
# Results
$DogACL = Get-Acl -Path "C:\Dog.txt"
Set-Acl -Path "C:\Cat.txt" -AclObject $DogACL
Get-Acl -Path "C:\Dog.txt" |
Set-Acl -Path "C:\Cat.txt"
$NewAcl = Get-Acl File0.txt
Get-ChildItem -Path "C:\temp" -Recurse -Include "*.txt" -Force |
Set-Acl -AclObject $NewAcl
#>
Get-help -Name Set-Acl -Full
Get-help -Name Set-Acl -Online
There are other modules via the Microsoft PowerShellGallery.com for you to leverage as well.
Find-Module -Name '*acl*', '*ntfs*' |
Format-Table -AutoSize
<#
# Results
Version Name Repository Description
------- ---- ---------- -----------
1.0.1 ACL-Permissions PSGallery A couple of ACL utilities, for repairing c...
1.30.1.28 ACLReportTools PSGallery Provides Cmdlets for reporting on Share ACLs.
1.7 ACLHelpers PSGallery Modules to help work with ACLs (Access Control Rights)
1.0.1.0 ACLCleanup PSGallery A set of tools to help you clean your files...
0.1.2 ACLTools PSGallery Module for managing NTFS Acls on files and folders
...
0.4 FileAclTools PSGallery Tools for quickly fixing file system ACLs
...
4.2.6 NTFSSecurity PSGallery Windows PowerShell Module for managing file ...
1.4.1 cNtfsAccessControl PSGallery The cNtfsAccessControl module contains DSC re...
1.0 NTFSPermissionMigration PSGallery This module is used as a wrapper to the popular ...
#>
So, for what you are showing
# Review current settings
Get-Acl -Path $env:SystemDrive |
Format-List -Force
<#
# Results
Path : Microsoft.PowerShell.Core\FileSystem::C:\Windows\system32
Owner : NT SERVICE\TrustedInstaller
Group : NT SERVICE\TrustedInstaller
Access : CREATOR OWNER Allow 268435456
NT AUTHORITY\SYSTEM Allow 268435456
NT AUTHORITY\SYSTEM Allow Modify, Synchronize
BUILTIN\Administrators Allow 268435456
BUILTIN\Administrators Allow Modify, Synchronize
BUILTIN\Users Allow -1610612736
BUILTIN\Users Allow ReadAndExecute, Synchronize
NT SERVICE\TrustedInstaller Allow 268435456
NT SERVICE\TrustedInstaller Allow FullControl
APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES Allow ReadAndExecute, Synchronize
APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES Allow -1610612736
APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES Allow ReadAndExecute, Synchronize
APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES Allow -1610612736
Audit :
Sddl : O:S-1-5-80-956008885-34...
#>
Description
The Set-Acl cmdlet changes the security descriptor of a specified
item, such as a file or a registry key, to match the values in a
security descriptor that you supply.
To use Set-Acl, use the Path or InputObject parameter to identify the
item whose security descriptor you want to change. Then, use the
AclObject or SecurityDescriptor parameters to supply a security
descriptor that has the values you want to apply. Set-Acl applies the
security descriptor that is supplied. It uses the value of the
AclObject parameter as a model and changes the values in the item's
security descriptor to match the values in the AclObject parameter.
Parameters
-AclObject Specifies an ACL with the desired property values. Set-Acl changes the ACL of item specified by the Path or InputObject parameter
to match the values in the specified security object.
You can save the output of a Get-Acl command in a variable and then
use the AclObject parameter to pass the variable, or type a Get-Acl
command.
TABLE 1 Type: Object
Position: 1 Default value: None Accept
pipeline input: True (ByValue) Accept wildcard characters: False
So, you just do something like this... as per the above examples
$AclSettings = 'WhatEverSettingsYouWant'
Set-Acl -Path $env:SystemDrive -AclObject $AclSettings
A similar question on StackOverflow is here:
Setting Inheritance and Propagation flags with set-acl and
Powershell
Then there is this guidance:
Here's the MSDN page describing the flags and what is the result of
their various combinations.
https://msdn.microsoft.com/en-us/library/ms229747(v=vs.100).aspx
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit
PropagationFlags.None
Here's some succinct PowerShell code to apply new permissions to a
folder by modifying its existing ACL (Access Control List).
# Get the ACL for an existing folder
$existingAcl = Get-Acl -Path 'C:\DemoFolder'
# Set the permissions that you want to apply to the folder
$permissions = $env:username, 'Read,Modify', 'ContainerInherit,ObjectInherit', 'None', 'Allow'
# Create a new FileSystemAccessRule object
$rule = New-Object -TypeName System.Security.AccessControl.FileSystemAccessRule -ArgumentList $permissions
# Modify the existing ACL to include the new rule
$existingAcl.SetAccessRule($rule)
# Apply the modified access rule to the folder
$existingAcl | Set-Acl -Path 'C:\DemoFolder'
<#
Each of the values in the $permissions variable list pertain to the parameters of this constructor for the FileSystemAccessRule class.
#>

How can I set desktop.ini ACL to allow me to delete it?

I'm trying to delete some users from AD and also take out their home directories. However, we have a script that denies us Administrators rights to their desktop.ini's because that stops their folder name being resolved in Explorer. However, when I want to blow out their whole home directory, the fact that there desktop.ini is still there means the parent folder can't be deleted either. I thought the below script would give me rights but it hasn't. What am I missing guys?
If (Test-Path $homeDir) {
$user = $_.uname
Set-ItemProperty -Path "\\server\students\home\$user" -Name Attributes -Value "Normal"
$acl = Get-Acl "\\server\students\home\$user"
$acl.access | where-object {$_.AccessControlType -eq "Deny"} | Foreach-object { $acl.RemoveAccessRule($_) }
(Get-Item "\\server\students\home\$user").SetAccessControl($acl)
Get-ChildItem -Path "\\server\students\home\$user\*" -Recurse | Remove-Item -Force -Recurse
Remove-Item "\\server\students\home\$user" -Recurse
Write-host "$user's home directory deleted successfully"
}
It's external to PowerShell (runs within PS just fine though) but I would suggest using icalcs as it makes this much simpler...
icacls "\\server\students\home\$user" /grant administrators:F /t