Security Cookbook
Security Cookbook
6. Adding Permissions
7. Removing Permissions
This issue compiles security-related code snippets from our daily tips column. Please note that this document by no means
aims to be a complete coverage. It is most definitely not, yet contains many very useful code snippets.
If you have snippets of your own that you are willing to share, you are most welcome. We will update our issues regularly and
are happy to include your feedback. Send your snippets to tobias@powertheshell.com.
PS> Get-ExecutionPolicy
Restricted
End users should use the setting RemoteSigned. It will allow you to run local scripts but will not allow scripts from outside the
network domain, or downloaded scripts from the Internet (except if the script has a valid digital signature which most scripts
wont have).
Professional scripters can use Bypass which will allow you to run any script, regardless of location. Unrestricted in contrast
will also let you run all scripts but will pop up a confirmation each time you are trying to run a script from a remote location.
Here is the line to change the execution policy for your own user account:
ExecutionPolicy
--------------Undefined
Undefined
Undefined
Bypass
RemoteSigned
As you can see, there are five execution policies. PowerShell goes from top to down, and the first one that is not Undefined
becomes the effective execution policy. If all are Undefined, then the resulting policy is Restricted that is the default
behavior on new systems. Only Windows Server 2012 R2 defaults to RemoteSigned
The scopes MachinePolicy and UserPolicy are set by Active Directory group policies. If these are set, then they override all
policies below.
The scope Process is valid only in the current PowerShell session. This is the policy that gets set when you run powershell.exe
with the -ExecutionPolicy parameter.
This outputs the SDDL for a file (make sure the file exists or specify a different file or folder):
$DogACL = Get-Acl -Path c:\test\dog.txt
$DogSDDL = $DogACL.GetSecurityDescriptorSddlForm(All)
$DogSDDL
The same code could display the SDDL for a registry key. Just change the path:
$DogACL = Get-Acl -Path HKCU:\Software
$DogSDDL = $DogACL.GetSecurityDescriptorSddlForm(All)
$DogSDDL
6. Adding Permissions
To add new permissions to an existing security descriptor, create an appropriate AccessRule object and configure it.
This script adds a new FileSystemAccessRule to the security descriptor of a file, granting read and write access to mydomain\
myaccount.
Author Bio
Tobias Weltner is a long-term Microsoft PowerShell MVP, located in Germany. Weltner offers entry-level and advanced PowerShell
classes throughout Europe, targeting mid- to large-sized enterprises. He organizes the annual German PowerShell Conference,
has published four PowerShell books (MS Press Germany) and is a regular speaker at conferences such as the PowerShell Summit
in Amsterdam. As a developer and software architect, Weltner recently published the commercial PowerShell ISE extension
ISESteroids, turning the built-in PowerShell editor into a sophisticated development environment (http://www.powertheshell.com/
isesteroids/).
To find out more about public and in-house training, get in touch with him at tobias.weltner@email.de.
Make sure you adjust both user account and filename before you test the code:
$colRights = [System.Security.AccessControl.FileSystemRights]Read, Write
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]::None
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow
$objUser = New-Object System.Security.Principal.NTAccount(mydomain\myaccount)
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule `
($objUser, $colRights, $InheritanceFlag, $PropagationFlag, $objType)
# get original SD
$catACL = Get-Acl C:\test\cat.txt
# add permission
$catACL.AddAccessRule($objACE)
# write back the appended SD
Set-Acl C:\test\cat.txt $catACL
You can use the same technique for other PowerShell drives, such as the registry. Just make sure you create the appropriate AccessRule object. To add permissions to registry keys, use a RegistryAccessRule object instead of a FileSystemAccessRule object.
7. Removing Permissions
To selectively remove a permission from a security descriptor, get access to the access control entries, pick the ones to remove,
and then write back the changed security descriptor.
This example removes all permissions and denials for the account mydomain\myaccount. Make sure you adjust both account
and filename before you test the code.
$catACL = Get-Acl c:\test\cat.txt
$unwanted = $catACL.Access |
Where-Object { $_.IdentityReference.Value -eq mydomain\myaccount }
$unwanted | ForEach-Object { $null = $catACL.RemoveAccessRule($_) }
Set-Acl -Path c:\test\cat.txt -AclObject $catACL
Powershell Plus
FREE TOOL TO LEARN AND MASTER POWERSHELL FAST
Learn PowerShell fast with the interactive learning center
Execute PowerShell quickly and accurately with a Windows UI console
Access, organize and share pre-loaded scripts from the QuickClick library
Code & Debug PowerShell 10X faster with the advanced script editor
As you see, Convert-SID2User actually returns Identities (not just users but also groups, as you can see in this example).
PS> [System.Security.Principal.WindowsIdentity]::GetCurrent()
AuthenticationType
ImpersonationLevel
IsAuthenticated
IsGuest
IsSystem
IsAnonymous
Name
Owner
User
Groups
:
:
:
:
:
:
:
:
:
:
LiveSSP
None
True
False
False
False
TOBI2\Tobias
S-1-5-21-1907506615-3936657230-2684137421-1001
S-1-5-21-1907506615-3936657230-2684137421-1001
{S-1-1-0, S-1-5-21-1907506615-3936657230-2684137421-1002,
S-1-5-32-559, S-1-5-32-545...}
4892
{http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nam
e: TOBI2\Tobias, http://schemas.microsoft.com/ws/2008/06/i
dentity/claims/primarysid:
S-1-5-21-1907506615-3936657230-2684137421-1001, http://sch
emas.microsoft.com/ws/2008/06/identity/claims/groupsid:
S-1-1-0, http://schemas.xmlsoap.org/ws/2005/05/identity/cl
aims/denyonlysid: S-1-5-114...}
{}
{http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nam
e: TOBI2\Tobias, http://schemas.microsoft.com/ws/2008/06/i
dentity/claims/primarysid:
S-1-5-21-1907506615-3936657230-2684137421-1001, http://sch
emas.microsoft.com/ws/2008/06/identity/claims/groupsid:
S-1-1-0, http://schemas.xmlsoap.org/ws/2005/05/identity/cl
aims/denyonlysid: S-1-5-114...}
Token
UserClaims
:
:
DeviceClaims
Claims
:
:
Actor
BootstrapContext
Label
NameClaimType
RoleClaimType
:
:
:
: http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
: http://schemas.microsoft.com/ws/2008/06/identity/claims/gr
oupsid
PS> [System.Security.Principal.WindowsIdentity]::GetCurrent().User.Value
S-1-5-21-1907506615-3936657230-2684137421-1001
You will get back the SIDs of all groups you are in. To translate the SIDs to real group names, use the Convert-SID2User function
covered before:
[System.Security.Principal.WindowsIdentity]::GetCurrent().Groups |
Select-Object -ExpandProperty Value |
Convert-SID2User
You could use this approach in logon scripts to check whether a user is member of a particular group.
So this would be a function you can use to ask for a hidden password and use the plain text entered in your script:
function Get-PasswordString
{
param
(
$Prompt = Enter Password
)
$password = Read-Host -AsSecureString $Prompt
(New-Object System.Management.AUtomation.PSCredential(dummy,$password)).
GetNetworkCredential().password
}