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.
#>
Related
Has anyone tried to or know how to setup a remote or cached repo within Artifactory for the powershellgallery?
I am unable to find anything even remotely talking about this online as well.
PSGallery URI is: https://www.powershellgallery.com/api/v2
I am beginning to think it was intentionally made by MS to not allow situations like that (but am looking for confirmation if that's the case)
NOTE: the intent here is that we will then have an internally accessible remote repo that is a copy of the PSGallery. Which then allows us to make sure we are scanning the modules and abiding by compliance regulations.
when it's added to Artifactory as a remote repo, its successful, but is empty.
Then, we set it up on Windows machine with register-PSRepository -Name psgallery-remote -SourceLocation myartifactoryuri (successful)
But when trying to do a find-module -name InvokeBuild -repository psgallery-remote it fails with no results.
When doing find-module -name InvokeBuild -Repository PSGallery it's successful.
You have to set up your repo and save PSGallery modules to it, then make it available to the local environment.
For a quick and dirty example to get stuff and use them:
New-Item -Path 'C:\' -Name 'LocalPSGallery' -ItemType Directory -Force -Verbose
Register-PSRepository -Name LocalPSGallery -SourceLocation 'C:\LocalPSGallery' -InstallationPolicy Trusted -Verbose
Get-PSRepository
Get-ChildItem -Path 'C:\LocalPSGallery'
# Results
<#
Note it is empty because it should be.
The above commands do not create a clone, it just sets up you local repo pointer.
#>
# Select a set number of modules as a test or by named group, etc
Find-Module -Name '*' |
Select-Object -First 9 |
Save-Module -Path 'C:\LocalPSGallery' -Force -ErrorAction SilentlyContinue
Get-ChildItem -Path 'C:\LocalPSGallery' # requested modules are listed
# Note still no list, because no path to your repo
Find-Module -Name Carbon -Repository LocalPSGallery
# Results
<#
PackageManagement\Find-Package : No match was found for the specified search
criteria and module name 'Carbon'. Try Get-PSRepository to see all available
registered module repositories.
#>
# Add the path
$env:PSModulePath
$env:PSModulePath = "$env:PSModulePath;C:\LocalPSGallery"
$env:PSModulePath
# Note still no list, because you've not installed anything
Find-Module -Name Carbon -Repository LocalPSGallery
# Results
<#
PackageManagement\Find-Package : No match was found for the specified search
criteria and module name 'Carbon'. Try Get-PSRepository to see all available
registered module repositories.
#>
# Try and install your module first
Install-Module -Name Carbon -Repository 'LocalPSGallery' -Verbose
# Results
<#
VERBOSE: Repository details, Name = 'LocalPSGallery', Location = 'C:\LocalPSGallery'; IsTrusted = 'True'; IsRegistered = 'True'.
VERBOSE: Using the provider 'PowerShellGet' for searching packages.
VERBOSE: Using the specified source names : 'LocalPSGallery'.
VERBOSE: Getting the provider object for the PackageManagement Provider 'NuGet'.
VERBOSE: The specified Location is 'C:\LocalPSGallery' and PackageManagementProvider is 'NuGet'.
VERBOSE: Total package yield:'0' for the specified package 'Carbon'.
PackageManagement\Install-Package : No match was found for the specified search
criteria and module name 'Carbon'. Try Get-PSRepository to see all
available registered module repositories.
#>
# Direclty import via FQDN
Import-Module -FullyQualifiedName 'C:\LocalPSGallery\Carbon' -Force -Verbose
# Results
<#
VERBOSE: Loading module from path 'C:\LocalPSGallery\Carbon\2.12.0\Carbon.psd1'.
VERBOSE: Loading 'FormatsToProcess' from path 'C:\LocalPSGallery\Carbon\2.12.0\Carbon.format.ps1xml'.
VERBOSE: Loading 'FormatsToProcess' from path 'C:\LocalPSGallery\Carbon\2.12.0\Formats\Carbon.Security.HttpUrlAcl.format.ps1xml'.
VERBOSE: Loading 'FormatsToProcess' from path 'C:\LocalPSGallery\Carbon\2.12.0\Formats\Schedule.Service.RegisteredTask.format.ps1xml'.
VERBOSE: Populating RepositorySourceLocation property for module Carbon.
VERBOSE: Loading module from path 'C:\LocalPSGallery\Carbon\2.12.0\Carbon.psm1'.
VERBOSE: Importing function 'Add-CGroupMember'.
VERBOSE: Importing function 'Add-CTrustedHost'.
...
#>
Find-Module -Name Carbon -Repository LocalPSGallery
# Results
<#
PackageManagement\Find-Package : No match was found for the specified search criteria
and module name 'Carbon'. Try Get-PSRepository to see all available
registered module repositories.
#>
# The below will work as expected
Get-Module -Name Carbon
Get-Module -ListAvailable
Here is a blog on the use case as well.
MS does provide the full details offline PSGallery deployment, See: Working with Private PowerShellGet Repositories
Of course, downloading all modules is going to take a very long time, and again, has would need to be done regularly to stay current.
So, on a pristine system, and using the details from the MS doc, you'd end up with something link this:
# Create a new location for your repo
New-Item -Path 'C:\' -Name 'LocalPSGallery' -ItemType Directory -Force -Verbose
# Update your path for your repo
$env:PSModulePath
$env:PSModulePath = "$env:PSModulePath;C:\LocalPSGallery"
$env:PSModulePath
# While online, install required resources
'PackageManagement', 'OfflinePowerShellGetDeploy' |
ForEach-Object {Install-Module -Name $PSitem -Force -Verbose}
Get-PSRepository
# Register a location for your repo
$CreateLocalPSGallery = #{
Name = 'LocalPSGallery'
SourceLocation = 'C:\LocalPSGallery'
ScriptSourceLocation = 'C:\LocalPSGallery'
InstallationPolicy = 'Trusted'
}
Register-PSRepository #CreateLocalPSGallery -Verbose
Get-PSRepository
Get-ChildItem -Path 'C:\LocalPSGallery'
# Publish from the PSGallery to your local Repository
Find-Module -Name '*' |
Select-Object -First 9 |
ForEach-Object {
$PublishFromLocalRepo = #{
Name = $PSItem.Name
Provider = 'NuGet'
Source = 'https://www.powershellgallery.com/api/v2'
Path = 'C:\LocalPSGallery'
Force = $True
ErrorAction = 'SilentlyContinue'
}
Save-Package #PublishFromLocalRepo
}
# Validate resource download
Get-ChildItem -Path 'C:\LocalPSGallery'
# Validate all repo resources
Find-Module -Name '*' -Repository LocalPSGallery
Find-Module -Name '*json*' |
Select-Object -First 3
# Make you repo the default - remote all other repos
Unregister-PSRepository -Name PSGallery -Verbose
Get-PSRepository
# Test your repo as the default
Find-Module -Name '*' -Repository LocalPSGallery
Find-Module -Name '*'
# After testing, reset the default
Register-PSRepository -Default -Verbose
Get-PSRepository
You should configure Artifactory remote repository as the following :
Url: https://www.powershellgallery.com/
NuGet Download Context Path : api/v2/package
NuGet Feed Context Path: api/v2
Link for JFrog documentation on NuGet Remote Repositories : https://www.jfrog.com/confluence/display/JFROG/NuGet+Repositories#NuGetRepositories-RemoteRepositories
I plan to update some files via PowerShell. Will Set-Content keep the access rights (ACL) or do I have to backup and restore these rights explicitly?
Set-Content (and Add-Content) and Out-File / > (>>) do not recreate an existing target file, they replace (append to) its contents, so its ACLs are preserved.
You can verify this with the following example code:
Push-Location $env:TEMP
Remove-Item tmp.txt -EA SilentlyContinue
# Create file 'tmp.txt with default ACL.
'original content' | Set-Content tmp.txt
# Modify the ACL to allow the Guests groups read access.
$acl = Get-Acl tmp.txt
$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule Guests, Read, Allow))
Set-Acl tmp.txt $acl
'ACL *before* Set-Content:'
(Get-Acl tmp.txt).Access.IdentityReference | Out-Host
# Use Set-Content to replace the existing content.
'new content' | Set-Content tmp.txt
# Verify that the file's ACL hasn't changed.
'ACL *after* Set-Content:'
(Get-Acl tmp.txt).Access.IdentityReference | Out-Host
Remove-Item tmp.txt
The above yields something like the following, showing that the custom ACL was preserved even after replacing the file's content with Set-Content:
ACL *before* Set-Content:
Value
-----
BUILTIN\Guests
NT AUTHORITY\SYSTEM
BUILTIN\Administrators
WS1\jdoe
ACL *after* Set-Content:
Value
-----
BUILTIN\Guests
NT AUTHORITY\SYSTEM
BUILTIN\Administrators
WS1\jdoe
I have a large list of folders within a single folder directory. My network rules are set where ntfs permissions are not inherited. I need to assign read and write permissions to each individual folder for the same 4 users to each of these individual folders is there a script for this?
Thanks for your assistance!
All you need is to get to your goal is here:
# Get parameters, examples, full and Online help for a cmdlet or function
(Get-Command -Name Get-Acl).Parameters
Get-help -Name Get-Acl -Examples
Get-help -Name Get-Acl -Full
Get-help -Name Get-Acl -Online
(Get-Command -Name Set-Acl).Parameters
Get-help -Name Set-Acl -Examples
Get-help -Name Set-Acl -Full
Get-help -Name Set-Acl -Online
(Get-Command -Name Get-NTFSAccess).Parameters
Get-help -Name Get-NTFSAccess -Examples
Get-help -Name Get-NTFSAccess -Full
Get-help -Name Get-NTFSAccess -Online
(Get-Command -Name Add-NTFSAccess).Parameters
Get-help -Name Add-NTFSAccess -Examples
Get-help -Name Add-NTFSAccess -Full
Get-help -Name Add-NTFSAccess -Online
PowerShell – Editing permissions on a file or folder
I've been trying to figure out how to change permissions on a folder in PowerShell. I've looked at the Get-Acl and Set-Acl, but I can only use them to copy the settings from a pre-existing object. How do I manually configure permissions?
This is actually a quite common question, so I thought I'd write a quick post on the subject.
https://blogs.msdn.microsoft.com/johan/2008/10/01/powershell-editing-permissions-on-a-file-or-folder
Weekend Scripter: Use PowerShell to Get, Add, and Remove NTFS Permissions
Managing file and folder permissions in Windows PowerShell is not that easy, and there are numerous articles and blog posts describing how it works by using the .NET classes. This is far from being comfortable, and there is one major and one minor restriction:
• Path length
• Generic rights
This post introduces the NTFSSecurity module, which provides a bunch of cmdlets for managing permissions on NTFS drives. It does not use the Windows PowerShell way to access the file system, and it works around the MAX_PATH, which is 260 characters. (For more information, see Naming Files, Paths, and Namespaces). This is achieved thanks to AlphaFS.
https://blogs.technet.microsoft.com/heyscriptingguy/2014/11/22/weekend-scripter-use-powershell-to-get-add-and-remove-ntfs-permissions
So I've got the next path: C:\folder1\folder2\fileName. Looking in the security tab on the C:\folder1 there is Alice username with full permissions. But going to the C:\folder1\folder2\fileName Alice isn't there yet. How can I insert with powershell v2 Alice member recursively in C:\folder1 so that all the files under root C:\folder1 will also have the same Alice username set with full permissions.
I've tried:
$acl = Get-Acl C:\folder1
$permission = "domain\Alice","FullControl","Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
$acl.SetAccessRule($accessRule)
$acl | Set-Acl C:\folder1
But it doesn't seem to apply for the C:\folder1\folder1\fileName. Guess I'm trying to apply permissions for Alice, which doesn't exist yet in the last fileName item.
As you can see in the FileSystemAccessRule documentation, the class has a property for inheritance.
You have to add the property to your $permission
$permission = "domain\Alice",
"FullControl",
[System.Security.AccessControl.InheritanceFlags]"ContainerInherit",
[system.security.accesscontrol.PropagationFlags]"None",
"Allow"
$accessRule = New-Object System.Security.AccessControl.FileSystemAccessRule $permission
You could also recursively add the permissions by getting all child items with the Get-ChildItems cmdlet and piping them to the Set-Acl cmdlet like they have done in an examle in the documentation on microsoft site here: Set-Acl. Look at "Example 3: Apply a security descriptor to multiple files" or read below (copied from the page):
PS C:\> $NewAcl = Get-Acl File0.txt
PS C:\> Get-ChildItem -Path "C:\temp" -Recurse -Include "*.txt" -Force | Set-Acl - AclObject $NewAcl
These commands apply the security descriptors in the File0.txt file to all text files in the C:\Temp directory and all of its subdirectories.
The first command gets the security descriptor of the File0.txt file in the current directory and uses the assignment operator (=) to store it in the $NewACL variable.
The first command in the pipeline uses the Get-ChildItem cmdlet to get all of the text files in the C:\Temp directory. The Recurse parameter extends the command to all subdirectories of C:\temp. The Include parameter limits the files retrieved to those with the ".txt" file name extension. The Force parameter gets hidden files, which would otherwise be excluded. (You cannot use "c:\temp*.txt", because the -Recurse parameter works on directories, not on files.)
The pipeline operator (|) sends the objects representing the retrieved files to the Set-Acl cmdlet, which applies the security descriptor in the AclObject parameter to all of the files in the pipeline.
In practice, it is best to use the Whatif parameter with all Set-Acl commands that can affect more than one item. In this case, the second command in the pipeline would be "Set-Acl -AclObject $NewAcl -WhatIf". This command lists the files that would be affected by the command. After reviewing the result, you can run the command again without the Whatif parameter.
This is an example using ".txt" files but can be modified to apply to directories as well.
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)