问题
I have been writing a script Workflow:
- Get list all of fixed disks ( except cdrom , floppy drive , usb drive)
- to check if a path exists or not in PowerShell
- to check if a Deny permission already exists to a directory or not in PowerShell
- Set deny permission for write access for users My question are :
1- After file exist control like below , also I want to check if a Deny permission already exists to a directory. ("$drive\usr\local\ssl")
If(!(test-path $path))
{
New-Item -ItemType Directory -Force -Path $path
}
2- there are about 1000 machines. How can I improve this script ?
Thanks in advance,
script :
$computers = import-csv -path "c:\scripts\machines.csv"
Foreach($computer in $computers){
$drives = Get-WmiObject Win32_Volume -ComputerName $computer.ComputerName | Where { $_.drivetype -eq '3'} |Select-Object -ExpandProperty driveletter | sort-object
foreach ($drive in $drives) {
$path = "$drive\usr\local\ssl"
$principal = "users"
$Right ="Write"
$rule=new-object System.Security.AccessControl.FileSystemAccessRule($Principal,$Right,"Deny")
If(!(test-path $path))
{
New-Item -ItemType Directory -Force -Path $path
}
try
{
$acl = get-acl $folder
$acl.SetAccessRule($rule)
set-acl $folder $acl
}
catch
{
write-host "ACL failed to be set on: " $folder
}
#### Add-NTFSAccess -Path <path> -Account <accountname> -AccessType Deny -AccessRights <rightstodeny>
}
}
回答1:
The first thing I noticed is that in your code, you suddenly use an undefined variable $folder instead of $path.
Also, you get the drives from the remote computer, but set this $path (and try to add a Deny rule) on folders on your local machine:
$path = "$drive\usr\local\ssl"
where you should set that to the folder on the remote computer:
$path = '\\{0}\{1}$\usr\local\ssl' -f $computer, $drive.Substring(0,1)
Then, instead of Get-WmiObject, I would nowadays use Get-CimInstance which should give you some speed improvement aswell, and I would add some basic logging so you will know later what happened.
Try this on a small set of computers first:
Note This is assuming you have permissions to modify permissions on the folders of all these machines.
$computers = Import-Csv -Path "c:\scripts\machines.csv"
# assuming your CSV has a column named 'ComputerName'
$log = foreach ($computer in $computers.ComputerName) {
# first try and get the list of harddisks for this computer
try {
$drives = Get-CimInstance -ClassName Win32_Volume -ComputerName $computer -ErrorAction Stop |
Where-Object { $_.drivetype -eq '3'} | Select-Object -ExpandProperty driveletter | Sort-Object
}
catch {
$msg = "ERROR: Could not get Drives on '$computer'"
Write-Host $msg -ForegroundColor Red
# output a line for the log
$msg
continue # skip this one and proceed on to the next computer
}
foreach ($drive in $drives) {
$path = '\\{0}\{1}$\usr\local\ssl' -f $computer, $drive.Substring(0,1)
$principal = "users"
$Right = "Write"
if (!(Test-Path -Path $path -PathType Container)) {
$null = New-Item -Path $path -ItemType Directory -Force
}
# test if the path already has a Deny on write for the principal
$acl = Get-Acl -Path $path -ErrorAction SilentlyContinue
if (!$acl) {
$msg = "ERROR: Could not get ACL on '$path'"
Write-Host $msg -ForegroundColor Red
# output a line for the log
$msg
continue # skip this one and proceed to the next drive
}
if ($acl.Access | Where-Object { $_.AccessControlType -eq 'Deny' -and
$_.FileSystemRights -band $Right -and
$_.IdentityReference -like "*$principal"}) {
$msg = "INFORMATION: Deny rule already exists on '$path'"
Write-Host $msg -ForegroundColor Green
# output a line for the log
$msg
}
else {
$rule = [System.Security.AccessControl.FileSystemAccessRule]::new($Principal, $Right, "Deny")
# older PS versions use:
# $rule = New-Object System.Security.AccessControl.FileSystemAccessRule $Principal, $Right, "Deny"
try {
$acl.AddAccessRule($rule)
Set-Acl -Path $path -AclObject $acl -ErrorAction Stop
$msg = "INFORMATION: ACL set on '$path'"
Write-Host $msg -ForegroundColor Green
# output a line for the log
$msg
}
catch {
$msg = "ERROR: ACL failed to be set on: '$path'"
Write-Host $msg -ForegroundColor Red
# output a line for the log
$msg
}
}
}
}
# write the log
$log | Set-Content -Path "c:\scripts\SetAccessRuleResults.txt" -Force
来源:https://stackoverflow.com/questions/65527969/check-if-a-deny-permission-already-exists-to-a-directory-or-not-in-powershell