On which system is get-acl resolved? - powershell

I've inherited a Powershell script that a remote customer uses to recursively search for directories and exports (to csv) multiple ACL values including Path, Owner, FileSystemRights, IdentifyReference, and AccessControlType. The script works great, but I am curious as to how the flow actually takes place. Below is partial script to show code relevant to my question below.
//Partial script begin:
get-childitem $rootdir -recurse | where-object {$_.psIscontainer -eq $true} | foreach-object {
$a = ($_.Fullname)
$b = (get-acl $_.Fullname).Owner
$c = (get-acl $_.Fullname).Access
foreach ($c1 in $c) {
$d = $c1.FileSystemRights
$e = $c1.AccessControlType
//Partial script end.
To my question: If running this script on a remote system, using admin privileges and variable $rootdir = \\someshare, on which system does the get-acl get resolved...on the system hosting the folder structure, or the remote system running the PS script and mapped to the share folder?
Thanks.
// My original question may have been a bit nebulous, so hopefully I can clarify a bit. By using get-acl on a remote system and mapped to a server share folder, will invoking get-acl cause any resource hit on the server during the ACL resolution process...disk I/O, memory, CPU. I am not a programmer, so please bear with me as I try to formulate my question properly.

Assuming that you have all authentication correctly setup (you would run into a double-hop auth problem if i understand your plan correctly) the call to Get-Acl would be executed on the system the script is run on.

From the technet article on the Get-ACL cmdlet
The Get-Acl cmdlet enables you to retrieve the security descriptor
(access control list) for a file, a folder, or even a registry key
It retrieves NTFS persmission for any folder specified, including remote folders.
In your case, it would run from the machine the script is running from, and authenticate to the remote machine using the credentials supplied to retrieve the ACL

Related

Error when changing ownership and transferring access rights

I ran into a problem, wrote a script that compresses pdf files through a program and transfers rights to a new file by copying from the old one to differentiate access to new files.
Here is the part of the code that I have is the problem
$owner = $origFile.GetAccessControl().GetOwner([System.Security.Principal.SecurityIdentifier])
$newFile = Get-Item -Path $PathoutFile
$FileSecurity = new-object System.Security.AccessControl.FileSecurity
$FileSecurity.SetOwner($owner)
[System.IO.File]::SetAccessControl($newFile, $FileSecurity)
Get-Acl -Path $origFile | Set-Acl -Path $newFile
My problem is this:
I execute the script using domain administrator privileges, everything works fine. If I use a domain user account and grant maximum rights to the directory, a compressed file is saved in it, and in this case I get the error “Attempt to perform an unauthorized operation.
I do not want to run the script under the administrator account for a simple reason, I believe that such rights are redundant for this operation. My judgments may not be correct, please help in solving this problem.
P.s actions are performed on a network directory.
Thanks in advance.
I myself found a solution to my main problem using the NTFSSecurity PowerShell module.
The transfer of access rights was performed using the Get-NTFSAccess $filein | Add-NTFSAccess $fileout

TFS / Azure Devops - This access control list is not in canonical form and therefore cannot be modified

I cannot check code into Team Foundation Server source control. Visual Studio shows an error "This access control list is not in canonical form and therefore cannot be modified." It does not specify the path with the problematic ACL.
The access control list for a file or folder needs to be rewritten in canonical form. Because Visual Studio does not specify the path, the easiest way to fix this is to try several until it works. Open an administrator PowerShell prompt. I found that this does not necessarily work unless running as administrator, although no errors indicate that it fails. Powershell will be used to get and set the ACLs of several paths, doing so rewrites them in canonical form without any additional steps.
First try the directory where TFS stores the workspace files:
cd $env:localappdata
cd '.\Microsoft\Team Foundation\'
gci -Recurse | % { Get-Acl $_ | Set-Acl $_ } # rewrite ACLs for all child folders and files
$x = gi . # get current folder
Get-Acl $x | Set-Acl -Path $x # rewrite its ACL
Now try parent directories (repeat this procedure to recurse up - for me the problem was fixed once I rewrote the ACL for the AppData folder)
$x = $x.Parent # get the parent directory
$x # display the folder to the console so you know what path you are working on
Get-Acl $x | Set-Acl -Path $x # rewrite its ACL
If this does not work, try repeating these steps for your source control path and its parent directories.

How to create a folder on C: drive of several PCs in a network using powershell

I need to create a folder called "logs" on the C: drive of all the machines in my organisation. How can i do this using PowerShell?
I have a script to create the "logs" folder however i need a way to do this on more than 100 machines in Active Directory.
Any advice?
This is the script i'm using to create the folder on my machine:
New-Item -Path c:\Logs -ItemType directory -Force
Is there a way i can apply this script to my entire organisation?
Thanks.
This is not a duplicate as i am trying to do this in a domain environment to all the machines in my organisation and not just one remote server.
Since you said it was a domain environment, you don't need to use remote execution, you can access the computer's hard disks remotely.
Get-ADComputer -Filter * | %{ $logsPath = "\\$($_.Name)\c$\Logs"; if ((Test-Path $logsPath) -eq $false) { New-Item -Path $logsPath -ItemType Directory } }
You will want to filter the output of Get-ADComputer or it will apply to every computer in your domain including the servers.

Reset file/folder permissions & Set new permissions

Trying to use powershell to reset permissions on files/folders copied over from a Linux machine.
Structure looks similar to this
E:\Parent Folder - No inheritance - Group based permissions
|
|
Folder01 - No inheritance
|
|
Subfolders and file - Group based permissions, inheritance
Folder02 - No inheritance
|
|
Subfolders and file - Group based permissions, inheritance
Folder03 - No inheritance
|
|
Subfolders and file - Group based permissions, inheritance
Folder04 - No inheritance
|
|
User Folder - User based permissions, No Inheritance
|
|
Inheritance
The script currently first runs the takeown command, followed by the icacls.
I then loop through the first level of folders to disable the inheritance.
Then the permissions are applied to the folders.
Here is a sample of what I have. It just repeats itself for each specific permission I want to set.
Get-ChildItem -Path "$solidPath" -ErrorAction SilentlyContinue | ForEach-Object {
$Item = $_.FullName
If ( "$Item" -eq "E:\ParentFolder\Folder04" -or "$Item" -eq "E:\ParentFolder\Folder03" )
{
Write-Host "Do Not Touch" -ForegroundColor DarkRed
}
Else
{
$colRightsAdmin = [System.Security.AccessControl.FileSystemRights]"FullControl"
$InheritanceFlagAdmin = [System.Security.AccessControl.InheritanceFlags]::ContainerInHerit -bor [System.Security.AccessControl.InheritanceFlags]::ObjectInHerit
$PropagationFlagAdmin = [System.Security.AccessControl.PropagationFlags]::None
$objTypeAdmin = [System.Security.AccessControl.AccessControlType]::Allow
$objUserAdmin = New-Object System.Security.Principal.NTAccount("BUILTIN\Administrators")
$objACEAdmin = New-Object System.Security.AccessControl.FileSystemAccessRule($objUserAdmin, $colRightsAdmin, $objTypeAdmin)
$objACLAdmin = Get-ACL "$Item"
$objACLAdmin.AddAccessRule($objACEAdmin)
Set-ACL "$Item" $objACLAdmin
I am using takeown + icacls to try and reset all the permissions. This initially worked well because the inheritance flags get reset as well.
I then use the method described in the link to set the appropriate permissions and inheritance on my folders and let the inheritance do the rest - Powershell & .net
The script worked on my test directory structure. But after coping the folders and files over I am getting a permission denied message when the icacls command runs (the takeown command runs without issue). The rest of the script then fails.
I know that I can use the RemoveAccessRule($objACE) to remove permissions from objects, but I haven't been able to figure out how to do it for all the user permissions that are defined.
I would like to start the folders and files off with a clean slate, and then apply permissions. All the examples I have found only show how to remove permissions for a specific user.
Where am I going wrong with the initial permission cleanup?
I ended up going with a bit of messy solution.
After I had a synced copy of the data from the Linux server I used robocopy to "move" all the data from one folder to another. This completely reset all the permissions on all the files.
After having done that I learned a little bit more about setting permissions and realized that I had been making a mistake all along.
I was aimlessly using this object to remove permissions
$acl.RemoveAccessRule($ace) | Out-Null
This was actually removing all privilege on the file before I had a chance to set any other permissions. So I was removing my ability to adjust permissions.
Once I realized this I used a combination of the properties IdentityReference and IsInherited to selectively target which permissions I was going to remove.
The script is big and ugly, but seems to work.

Count files in a network folder using PowerShell

I've searched numerous MSDN/Technet and StackOverflow articles regarding this but I can't find a solution to my problem.
SO references below.
I am trying to run a script on my server that simply counts the files in a folder on a network location.
I can get it working if it's a local folder, and I can get it working when I map the network drive. However I can't use a network drive because I'll be running this script from a web interface that doesn't have a user account (local drives work fine).
My script is:
$Files = Get-ChildItem \\storage\folder -File
$Files.count
I get the error:
Get-ChildItem : Cannot find path '\\storage\folder' because it does not exist.
[0]open folder from Network with Powershell
[1]File counting with Powershell commands
[2]Count items in a folder with PowerShell
[3]Powershell - remote folder availability while counting files
Two things that I can think of,
One would be to add -path to your get-childitem call. I tested this on my Powershell and it works fine.
$files = get-childitem -path C:\temp
$files.count
This returns the number of files in that path.
However I am testing this on a local file. If you are sure it is the remote access part giving you trouble I would suggest trying to set credentials. Besides the get-credentials option, you could also try setting them yourself.
$Credentials = New-Object System.Management.Automation.PsCredential("Username", "password")
Then perhaps you can set the drive and still be able to access your files. Hope that helps.
Try this:
set-location \\\storage\folder\
dir -recurse | where-object{ $_.PSIsContainer } | ForEach{ Write-Host $_.FullName (dir $_.FullName | Measure-Object).Count }
This will count the number of files in each sub-folder (recurse) and display the full path and count in the output.