Write-Protect System Variables - windows

I'm trying to create a script to write-protect the environment variables and then unlock them whenever we need a script to update them. We've recently had a rash of "admins" that can't read and have been completely wiping out the entire %PATH% variable when told to add a single entry.
I've worked out how we can script that so that there's less risk of such things, but I'd also like to have %PATH% uneditable except for when we need it.
I've successfully created a PowerShell function that does this, however it also prevents me from removing the rule when it needs to be edited. I've left all the default permissions on the key alone, as I ONLY want to add a restriction against editing the keys themselves.
function regLock
{
Write-Host "LOCKING SYSTEM ENVIRONMENT VARIABLES" -ForegroundColor Yellow
$key = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
$acl = Get-Acl $key
$rule = New-Object System.Security.AccessControl.RegistryAccessRule("Administrators", "SetValue", "None", "InheritOnly" , "Deny")
$acl.SetAccessRule($rule)
Set-Acl -AclObject $acl -Path $key
}
function regUnlock
{
Write-Host "UNLOCKING SYSTEM ENVIRONMENT VARIABLES" -ForegroundColor Green
$key = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Environment'
$acl = Get-Acl $key
$rule = New-Object System.Security.AccessControl.RegistryAccessRule("Administrators", "SetValue", "None", "InheritOnly" , "Deny")
$acl.RemoveAccessRule($rule)
Set-Acl -AclObject $acl -Path $key
}
Of course if I go into regedit I can remove the lockout key, but that defeats the purpose of keeping them out of places they shouldn't be. I thought the SetValue permission only applied to changing/creating values, not ACL permissions.

Related

assign more users to folder on powershell

everyone please help me, I need a command to assign permissions to a folder in the directory tree, conditional on the correct directory name to be assigned. I am trying to write a command line but when assigning a group or a user, it can be assigned but other users are removed, I want to not remove any users.
$mypath = "D:\KIEM TRA1"
$myacl = Get-Acl $mypath
$myaclentry = "EMC0\test.ktnb","readandexecute,write","Allow"
$myaccessrule = New-Object System.Security.AccessControl.FileSystemAccessRule($myaclentry)
$myacl.SetAccessRule($myaccessrule)
Get-ChildItem -Path "$mypath" -Recurse -Force |
Where-Object { $_.Name -eq 'A' -or $_.Name -eq 'B' } |
Set-Acl -AclObject $myacl -Verbose
I want to do it on a subdirectory and not remove the existing user
I guess what you need is to create a new access rule using 5 parameters, so you can handle inheritance and propagation too.
Try this (always on a set of test folders first of course..)
$mypath = "D:\KIEM TRA1"
$account = "EMC0\test.ktnb"
# see: https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.filesystemrights
# https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.inheritanceflags
# https://learn.microsoft.com/en-us/dotnet/api/system.security.accesscontrol.propagationflags
$rule = [System.Security.AccessControl.FileSystemAccessRule]::new($account, "Modify", "ContainerInherit,ObjectInherit", "None", "Allow")
# on older PowerShell versions use:
# $rule = New-Object System.Security.AccessControl.FileSystemAccessRule($account, "Modify", "ContainerInherit,ObjectInherit", "None", "Allow")
# get a list of folder FullNames of subfolders with name 'A' or 'B'
$folders = (Get-ChildItem -Path $mypath -Directory -Recurse | Where-Object { $_.Name -match '^[AB]$' }).FullName
foreach ($directory in $folders) {
# get the current ACL of the folder
$acl = Get-Acl -Path $directory
# add the new rule to the ACL
$acl.AddAccessRule($rule)
$acl | Set-Acl -Path $directory -Verbose
}
Note:
Instead of AddAccessRule(), you might prefer SetAccessRule().
AddAccessRule
This method will add this access rule to the ACL.
If a user has Modify permission and we use AddAccessRule() to create a new rule with Read permission the user will still also have Modify permissions.
SetAccessRule
This method removes any existing access an replaces that access with the specified rule.
If a user has Modify permission and a new rule is created using SetAccessRule() specifying Read permission, that user will now only have Read permission.

Batch Powershell User csv import and home folder creation

I'm trying to use a CSV import to create batch users but for it to also create users' home folder and profile folders but with setting permissions at the same time.
I've found a lot of helpful information online, I just don't know how to make the syntax work with what I already have which took me quite a long time to even get to.
This is my script so far for creating accounts on the domain controller and then syncing them with O365. We use a csv as we create tons of users at the same time:
Import-Csv "C:\blablabla\filename.csv" | ForEach-Object {
New-ADUser -Name $_.Name `
-GivenName $_."GivenName" `
-Surname $_."Surname" `
-DisplayName $_."DisplayName" `
-SamAccountName $_."samAccountName" `
-UserPrincipalName $_."UserPrincipalName" `
-Path $_."Path" `
-AccountPassword (ConvertTo-SecureString “Pa$$w0rd” -AsPlainText -force) -Enabled $true `
-EmailAddress $_."EmailAddress" `
-ProfilePath $_."ProfilePath" `
-HomeDrive $_."HomeDrive" `
-HomeDirectory $_."HomeDirectory" `
-ScriptPath $_."ScriptPath" `
-Server $_."Server" `
-OtherAttributes #{ProxyAddresses= $_."ProxyAddresses"} `
}
Start-ADSyncSyncCycle -PolicyType Initial
All the values point to columns in the excel file which auto-complete based on a user's first and last name.
I know I'm supposed to be creating the home and profile folders and setting permissions as per the below for example, I just don't know how to make the syntax work with what I already have?
So far, the values only get set in AD correctly but the folders don't get created and permissions aren't getting applied.
I guess I could just add an other command to create a new folder but I wouldn't know how to do append that to the foreach command?
New-Item -ItemType Directory -Path \\dc\userdata
$ACL = (Get-ACL -Path $HomeDirectory)
$FullControlAccessRule = (New-Object System.Security.AccessControl.FileSystemAccessRule([System.Security.Principal.NTAccount]"hcc.local\$UserName","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))
$ACL.AddAccessRule($FullControlAccessRule)
Set-ACL -Path $HomeDirectory $ACL
Any help would be greatly appreciated.
Thanks.
So, as per what NAS said, something like this then
?
-OtherAttributes #{ProxyAddresses= $_."ProxyAddresses"}
New-Item -ItemType Directory -Path $_.HomeDirectory
New-Item -ItemType Directory -Path $_.ProfilePath
$ACL = (Get-ACL -Path $_.HomeDirectory)
$FullControlAccessRule = (New-Object System.Security.AccessControl.FileSystemAccessRule(
[System.Security.Principal.NTAccount]"hcc.local\$($_.samAccountName)",
"FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))
$ACL.AddAccessRule($FullControlAccessRule)
Set-ACL -Path $_.HomeDirectory $ACL
$ACL = (Get-ACL -Path $_.ProfilePath)
$FullControlAccessRule = (New-Object System.Security.AccessControl.FileSystemAccessRule(
[System.Security.Principal.NTAccount]"hcc.local\$($_.samAccountName)",
"FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))
$ACL.AddAccessRule($FullControlAccessRule)
Set-ACL -Path $_.ProfilePath $ACL
Import-Csv "C:\blablabla\filename.csv" | ForEach-Object {
New-ADUser -Name $_.Name `
...
-OtherAttributes #{ProxyAddresses= $_."ProxyAddresses"} # Remove backtick
New-Item -ItemType Directory -Path $_.HomeDirectory # create home path if needed
New-Item -ItemType Directory -Path $_.ProfilePath # create profile path if needed
$ACL = (Get-ACL -Path $_.HomeDirectory) # No need for quotes around properties if they do not contain spaces or other special characters
$FullControlAccessRule = (New-Object System.Security.AccessControl.FileSystemAccessRule(
[System.Security.Principal.NTAccount]"hcc.local\$($_.samAccountName)", # replace $UserName with correct variable
"FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))
$ACL.AddAccessRule($FullControlAccessRule)
Set-ACL -Path $_.HomeDirectory $ACL
# -> # repeat for profile path if needed
}

Auditing Success and Failure event to folder

I'm using PowerShell to add users to auditing for folders in Windows 10.
I'm using this code to set "EVERYONE" for Auditing.
But I need to do special rules for fail and special rules for Success and Fail, so I need it to save in 2 different lines. - like this picture:
This is the code I'm using:
$Folders = "C:\windows\system32\config"
Foreach ($Folder in $Folders) {
Write-Host "" # Empty line
Write-Host "Applying Auditing for folder", $Folder
Write-Host "" # Empty line
$ACL = Get-Acl $Folder
# Set Auditing for Success event for above Folders for EVeryone group
$PermAudited = "CreateFiles"
$AccessRule = New-Object System.Security.AccessControl.FileSystemAuditRule("Everyone", $PermAudited, "Failure")
$ACL.SetAuditRule($AccessRule)
# Set Auditing for Success event for Top folder
Write-Host $Folder, "for auditing Success event"
$ACL | Set-Acl $Folder
}
You can Specify those rules using the System.Security.AccessControl.FileSystemRights enum, Check the available rules like this:
[enum]::GetNames([System.Security.AccessControl.FileSystemRights])
Basically you need to take a look on one of the Constructors for the FileSystemAuditRule to understand how you need to set it, for your needs I think this is the right one:
FileSystemAuditRule(
string identity,
FileSystemRights fileSystemRights,
AuditFlags flags
)
So, you need to set Rights and AuditFlags, based on your example it should be something like this:
$Rights = "ReadAndExecute","Modify"
$Flags = "Failure"
$AccessRights = [System.Security.AccessControl.FileSystemRights]$Rights
$AuditFlags = [System.Security.AccessControl.AuditFlags]$Flags
Then Set the ACL like this:
$ACL = Get-Acl $Folder
$AccessRule = New-Object System.Security.AccessControl.FileSystemAuditRule("Everyone",$AccessRights, $AuditFlags)
$ACL.SetAuditRule($AccessRule)
Set-Acl -Path $Folder -AclObject $ACL

How can I use powershell 4.0 set-acl to allow the user to have the same security settings in newly created subdirectories?

When I set user access via set-acl I can loop through all existing subfolders. How do I set it to include future subfolders created under the main folder?
Also... Once the access is set it only displays in 'Advanced' settings for the folders. The first security screen shows the user but shows no access rights.
This is in Windows Server 2012 R2.
$SubFolder = "name"
$UserName = "domain\" + $SubFolder
$Folder = "R:\User Files\" + $SubFolder + "\"
$Acl = Get-Acl $Folder
$Ar = New-Object system.security.accesscontrol.filesystemaccessrule($UserName,"FullControl","Allow")
$Acl.SetAccessRule($Ar)
#Get-Variable
Set-Acl -Path $Folder -AclObject $Acl
$Folder = Get-childItem $Folder
foreach ($TempFolder in $Folder)
{
$Folder = $TempFolder.FullName
$Acl = Get-Acl $Folder
$Ar = New-Object system.security.accesscontrol.filesystemaccessrule($UserName,"FullControl","Allow")
$Acl.SetAccessRule($Ar)
#Get-Variable
Set-Acl -Path $Folder -AclObject $Acl
}
You will need to set your Inheritance and Propagation flags in order for it to affect files and folders within your target. Here's my typical template that I use when I'm working on setting up new ACLs for users:
$Rights = [System.Security.AccessControl.FileSystemRights]"FullControl"
$InheritanceFlag = [System.Security.AccessControl.InheritanceFlags]"ObjectInherit,ContainerInherit"
$PropagationFlag = [System.Security.AccessControl.PropagationFlags]::None
$objType =[System.Security.AccessControl.AccessControlType]::Allow
#Define the user's account using their samAccountName
$objUser = New-Object System.Security.Principal.NTAccount("samAccountName")
$objACE = New-Object System.Security.AccessControl.FileSystemAccessRule($objUser, $Rights, $InheritanceFlag, $PropagationFlag, $objType)
$objACL = Get-ACL "C:\Temp"
$objACL.AddAccessRule($objACE)
Set-ACL "C:\Temp" $objACL
The settings here will make future things inherit the settings that you define for the target folder.

Changing share permissions using Powershell

I'm trying to modify the share permissions of share drives on a bunch of windows servers which are running either 2008 R2 or 2012.
I worked up a script which you can find here:
Import-Module ActiveDirectory
$list = Get-ADComputer -Filter 'SamAccountName -like "*FP*"' | Select -Exp Name
foreach ($Computer in $list)
{
Grant-SmbShareAccess -Name User -CimSession Server -AccountName "username" -AccessRight Full -confirm:$false
$acl = (Get-Item \\$Computer\d$\User ).GetAccessControl('Access')
$rule = New-Object System.Security.AccessControl.FileSystemAccessRule ("Corp\uc4serv","FullControl","ContainerInherit, ObjectInherit","None","Allow")
$acl.AddAccessRule($rule)
Set-Acl \\$Computer\d$\User $acl
Write-Host -ForegroundColor DarkGreen "Permissions granted on $Computer"
}
Write-Host -ForegroundColor DarkBlue "Command Has Completed"
But it doesn't work on 2008 servers presumably because they can't run the Get-SmbShareAccess cmdlet.
What I'm trying to do is very similar to this post here: How to set share permissions on a remote share with Powershell? but specifically on Windows servers.
I also found this code on a website (http://windowsitpro.com/powershell/managing-file-shares-windows-powershell):
$acl = Get-Acl `
\\servername\c$\Users\username\sharetest
$permission = "corp\uc4serv","FullControl","Allow"
$accessRule = New-Object `
System.Security.AccessControl.FileSystemAccessRule `
$permission
$acl.SetAccessRule($accessRule)
$acl |
Set-Acl \\servername\c$\Users\username\sharetest
But this just sets the Security on the share instead of the share permissions.
I also looked into using the Net Share command but in order to change share permissions with that, it has to delete and re-create the share drive completely.
You can use "Net Share". Use Invoke-Command to run it on each remote server.
Source - https://social.technet.microsoft.com/Forums/windowsserver/en-US/3edcabac-f1a8-4c4a-850c-8ba4697930a2/using-net-share-within-powershell
Example
Source - $server = "MYSRV" ; $user = "username" ; $SrvPath = "E:\Users\$user"
$sb = {
param($User,$SrvPath)
NET SHARE $User$=$SrvPath "/GRANT:Domain Admins,FULL" "/GRANT:$User,CHANGE" /REMARK:"Home folder for $SrvPath"
}
Invoke-Command -Computername "$Server" -ScriptBlock $sb -ArgumentList $user,$SrvPath

Resources