Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
826 views
in Technique[技术] by (71.8m points)

check if a Deny permission already exists to a directory or not in PowerShell

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. ("$driveusrlocalssl")

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:scriptsmachines.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 = "$driveusrlocalssl"
$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>


}

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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 = "$driveusrlocalssl"

where you should set that to the folder on the remote computer:

$path      = '\{0}{1}$usrlocalssl' -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:scriptsmachines.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}$usrlocalssl' -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:scriptsSetAccessRuleResults.txt" -Force

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...