Error when changing ownership and transferring access rights - powershell

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

Related

Grant permissions to a folder

How (which command) can I use to grant permissions (full_control) to a user (service_account) on a folder using PowerShell?
Thank you!
I was trying to use icacls in my PowerShell but it's not working.
There are several ways to do this. If you don't want to install a module as James suggests above then:
# Get current access permissions from folder and store in object
$Access = Get-Acl -Path $FolderPath
# Create new object with required new permissions
$NewRule = New-Object System.Security.AccessControl.FileSystemAccessRule("MyDomain\MyUserOrGroup","FullControl","ContainerInherit,ObjectInherit","None","Allow")
# Add new rule to our copy of the current rules
$Access.AddAccessRule($NewRule)
# Apply our new rule object to destination folder
Set-Acl -Path $FolderPath -AclObject $Access -ErrorAction Stop
As James mentions though, using ACLs in Powershell without a module, whilst powerful, is also a pain. I only do it when I'm sharing scripts (so that there isn't a dependency on the module).
I would recommend using the NTFSSecurity Powershell module for setting the permissions as it's much easier to use (and understand) than acls!
To add permissions for a user is just one command.
I've shown two examples for both network paths/domain account and local folder/local user. They can be mixed in any way you can set via the GUI.
Add-NTFSAccess -Path "\\sdk\data\SHAREDIR\$NAME" -Account "Domain\K_NV_TEST_R" -AccessRights FullControl
Add-NTFSAccess -Path "C:\folder\subfolder" -Account "LocalComputerName\LocalUserName" -AccessRights FullControl

temporarily take ownership of a folder

I need to temporarily take ownership of a profilefolder, in order to add permissions(ReadOnly) to members of a securitygroup. I would like to know how to achieve this in powershell.
I have before used TakeOwn.exe, but since it can't give ownership back to the original owner, I can't use it for this.
I tried using a module called PowerShellAccessControl, which I found on technet.
Import-Module $PSScriptRoot\modules\PowerShellAccessControl\PowerShellAccessControl.psd1
$path = "$PSScriptRoot\profileFolders\profile"
$AddAceParams = #{
Principal = "SecurityGroup"
FolderRights = "Read"
}
Get-SecurityDescriptor $path -PacSDOption (New-PacCommandOption -BypassAclCheck) | ForEach-Object {
$OriginalOwner = $_.Owner
$_ | Set-Owner -PassThru -Apply |
Add-AccessControlEntry #AddAceParams -PassThru |
Set-Owner -Principal $OriginalOwner -Apply
}
But this code only resultet in the following error:
New-PacCommandOption : The term 'New-PacCommandOption' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
I dont know if i should continue with this module or if there is a better way.
I tend to use the NTFSSecurity module when dealing with filesystem permissions, it's well written and I've had good success with it so far.
$path = "C:\folder"
$OriginalPermissions = Get-NTFSOwner $path
Set-NTFSOwner -Path $path -Account $env:USERNAME
Add-NTFSAccess -Path $path -Account 'DOMAIN\SecurityGroup' -AccessRights Read
Set-NTFSOwner -Path $path -Account $OriginalPermissions.Owner
Note: You do need to install the module, if you're using a modern version of Powershell this is easy as you can just use Install-Module -Name NTFSSecurity. If it's an older version you will need download and install the module manually.
EDIT:
The other option is to use Enable-Privileges to grant your account the privileges for Backup, Restore, and Security.
With these you will be able to edit the permissions without your own account having explicit permissions to the data. Use of these command is covered in the documentation in the link above. Be sure to Disable-Privileges after enabling them as it's not good practice to run with these all the time.

PowerShell Active Directory Login Script Auto-Build

I've created an active directory account creation script using powershell 4.
My Boss has stated there's a new policy where we have to build a login script per user, is there a way to do this where it'll build the .bat file and map the drives that we specify within the script?
I know there's a way to build .txt files, but not sure about .bat.
What I need
Select Drives That The user Needs Access To
I need it to build a .bat file, mapping the drives previously specified.
Then move it to the login script folder on the DC, mapped to S
For Future reference to anybody who wants to do this.
I've managed to resolve it myself after some playing around.
$NewName = $SAMAccountName
$extension = ".bat"
$FileName = "$SAMAccountName$extension"
$ScriptDrive = "\\IPREMOVED\scripts"
Write-Output "
BAT CONTENTS" `n`n|FT -AutoSize >>LoginScript.txt
Get-ChildItem LoginScript.txt | Rename-Item -NewName $FileName
Move-Item -Path ".\$FileName" -Destination $ScriptDrive

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.

On which system is get-acl resolved?

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