I am new in Powershell and i have a question : i'm using this command line to apply rights, which works perfectly :
import-module NtfsSecurity
$Adminfilesserver = "Domain\Admins"
$Path1 = "\\server\data"
Add-NTFSAccess -AccessRights FullControl -Account ($Adminfilesserver) -Path $Path1 -AccessType Allow -AppliesTo ThisFolderSubfoldersAndFiles -Verbose
-Verbose doesn't give me which files are processed by the command line if DATA already exists with files in it... Can someone tell me how can I proceed plz ? Thx. (sorry for the format, i've not been able to do it correctly)
Related
I'm trying to remove a bunch of OSX alternate data streams on an NTFS volume. However no matter what I try I cannot get Powershell to do it. Yes, I admit that my powershell is not great. Is anyone able to help?
Objective: Remove the ADS "AFP_AfpInfo" from any directory in the volume.
Current Code:
Get-ChildItem E:\ -Directory -Recurse | ForEach-Object {
$streams = Get-Content -Path $_ -Stream AFP_AfpInfo -ErrorAction SilentlyContinue
if ($streams) {
$streams | ForEach-Object {
try {
Remove-Item -Path "$($_.PSPath)" -Stream AFP_AfpInfo -Recurse -Force -ErrorAction Silentlycontinue
}
catch {
Write-Host "An error occurred: $($_.Exception.Message)"
}
}
}
}
Current error:
An error occurred: A parameter cannot be found that matches parameter name 'Stream'.
Note: Running Powershell 7.3
-Recurse and -Stream don't seem to go together even though in the documentation they appear in the same Parameter Sets. In this case -Recurse should be removed. GitHub Issue #9822 was submitted to add clarification to the Remove-Item doc.
Also, you're seeking for an exact stream, AFP_AfpInfo, so I don't see a need to enumerate $streams. Lastly, checking if a file or folder has an alternative stream should be done with Get-Item instead of Get-Content for efficiency.
As a final aside, the code must use the .Remove method from EngineIntrinsics to work, Remove-Item -Confirm:$false -Force will always ask for confirmation on folders, arguably a bug. Remove-Item should skip confirmation checks if -Stream is in use and -Confirm:$false -Force. GitHub issue #19154 was submitted to follow up on this.
$removeFunc = $ExecutionContext.InvokeProvider.Item.Remove
$targetStream = 'AFP_AfpInfo'
Get-ChildItem E:\ -Recurse -Directory | ForEach-Object {
if ($stream = $_ | Get-Item -Stream $targetStream -ErrorAction SilentlyContinue) {
try {
$removeFunc.Invoke($stream.PSPath, $false, $true, $true)
}
catch {
Write-Host "An error occurred: $($_.Exception.Message)"
}
}
}
Why are you not just using the Unblock-File cmdlet to remove ADS?
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/unblock-file?view=powershell-7.3
Description This cmdlet only works on the Windows and macOS platforms.
The Unblock-File cmdlet lets you open files that were downloaded from
the internet. It unblocks PowerShell script files that were downloaded
from the internet so you can run them, even when the PowerShell
execution policy is RemoteSigned. By default, these files are blocked
to protect the computer from untrusted files.
Before using the Unblock-File cmdlet, review the file and its source
and verify that it is safe to open.
Internally, the Unblock-File cmdlet removes the Zone.Identifier
alternate data stream, which has a value of 3 to indicate that it was
downloaded from the internet.
Get-Help -Name Unblock-FIle -Examples
NAME
Unblock-File
SYNOPSIS
Unblocks files that were downloaded from the internet.
------------------ Example 1: Unblock a file ------------------
PS C:\> Unblock-File -Path C:\Users\User01\Documents\Downloads\PowerShellTips.chm
-------------- Example 2: Unblock multiple files --------------
PS C:\> dir C:\Downloads\*PowerShell* | Unblock-File
------------- Example 3: Find and unblock scripts -------------
PS C:\> Get-Item * -Stream "Zone.Identifier" -ErrorAction SilentlyContinue
FileName: C:\ps-test\Start-ActivityTracker.ps1
See also Get-Item, Clear-Content and Remove-Item cmdlets use case:
Friday Fun with PowerShell and Alternate Data Streams
https://jdhitsolutions.com/blog/scripting/8888/friday-fun-with-powershell-and-alternate-data-streams
You could also just use the MSSysinternals tool to remove ADS as well in your PS code.
https://learn.microsoft.com/en-us/sysinternals/downloads/streams
I'm a bit new to Powershell and i'm trying to complete a simple script for a project I'm working on. I get it working 95% of the way but it just not returning the results. I have loaded the NTFSSECURITY Module and I'm using Add-NTFSACCESS to set Deny delete on multiple folders using the paths stored in a .csv file. See below.
Script
$itempath = import-csv "C:\dox\folderpath.csv"
foreach ($items in $itempath) {
Add-NTFSAccess -path $itempath -AccessRights Delete -Account "domain\username" -AccessType Deny -AppliesTo ThisFolderOnly
}
This is the error i get
Add-NTFSAccess : Unable to find the specified file.
Please help
Add-NTFSAccess -path $itempath this is telling powershell that the path to the item you want to change access to is an array of powershell objects that you imported from your CSV. You'll need to change that to $items.something with "something" being the heading of the column in your CSV file that contains the path.
OK Guys thanks a lot for your input. Its a simple script and what both of you said should work but I'm getting different errors. I found a way to do it without using a csv file but this was will apply the permission to all folders in the directory. Works for me. Please not you have to import the NTFSSECURITY Module to use Add-NTFSAccess
Get-ChildItem "\directory\path\" -Directory | % { $_.FullName} | Add-NTFSAccess -AccessRights Delete -Account "domain\username" -AccessType Deny -AppliesTo ThisFolderOnly
I have a file server where the users have their own diskspace. And I need to delete a certain folder on each users diskspace, but not all users have this folder. Also the users are divided into department, so the layout of the folders looks like this:
D:\users\departmentA\usernameA\foldertodelete
D:\users\departmentA\usernameB\foldertodelete
D:\users\departmentB\usernameC\foldertodelete
D:\users\departmentC\usernameD\foldertodelete
...
How can I make this happen? Im thinking of using Poweshell, and I have been reading about Test-Path, but I dont know how to work with this then the path is different for all the users.
This is fairly straightforward with PowerShell:
$TargetName = "foldertodelete"
$BaseDir = "D:\Users"
# Iterate over each department directory
foreach($Department in #(Get-ChildItem $BaseDir -Directory)){
# Within each department, iterate over each user directory
foreach($User in #(Get-ChildItem $Department -Directory)){
# Check if the undesirable folder exists
if([System.IO.Directory]::Exists(($TargetPath = Join-Path -Path $User -ChildPath $TargetName))){
# If so, remove the directory and all child items
Remove-Item $TargetPath -Recurse
}
}
}
The -Directory parameter on Get-ChildItem is available in PowerShell 3.0 and above. For PowerShell 2.0 you could use:
Get-ChildItem $BaseDir |Where {$_.PSIsContainer}
Thank you for your answer. I do have some problem making the script work. It looks like the script don't understand the BaseDir part. The department folder where the users have their folder is located on D:\Users. I copied the script to C:\skript. And the error message show that it is looking for the userfolder on my C drive. It should look on D:\users\AAL-users\username
Here is the error message:
PS C:\skript> .\RemoveFolder.ps1
Get-ChildItem : Cannot find path 'C:\skript\AAL-users' because it does not exist.
At C:\skript\RemoveFolder.ps1:7 char:22
+ foreach($User in #(Get-ChildItem $Department -Directory)){
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\skript\AAL-users:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
I did try to copy the script to my D:\users folder. This time I got no error messages, but the script did not delete any folders as it is suposed to.
Try the below...
Remove-Item -path D:\Users\* -Filter *specificnameof the folder* -WhatIf --(Whatif allows you to test a command before you run)
Remove whatif and execute the delete
Remove-Item -path C:\users\* -Filter *specificnameof the folder*
Here is the exact code I run now:
PS D:> Remove-Item -path "D:\DU Users*" -Filter notes85
PS D:>
No error messages, but also, the folder in question is not removed.
I'm trying to delete some users from AD and also take out their home directories. However, we have a script that denies us Administrators rights to their desktop.ini's because that stops their folder name being resolved in Explorer. However, when I want to blow out their whole home directory, the fact that there desktop.ini is still there means the parent folder can't be deleted either. I thought the below script would give me rights but it hasn't. What am I missing guys?
If (Test-Path $homeDir) {
$user = $_.uname
Set-ItemProperty -Path "\\server\students\home\$user" -Name Attributes -Value "Normal"
$acl = Get-Acl "\\server\students\home\$user"
$acl.access | where-object {$_.AccessControlType -eq "Deny"} | Foreach-object { $acl.RemoveAccessRule($_) }
(Get-Item "\\server\students\home\$user").SetAccessControl($acl)
Get-ChildItem -Path "\\server\students\home\$user\*" -Recurse | Remove-Item -Force -Recurse
Remove-Item "\\server\students\home\$user" -Recurse
Write-host "$user's home directory deleted successfully"
}
It's external to PowerShell (runs within PS just fine though) but I would suggest using icalcs as it makes this much simpler...
icacls "\\server\students\home\$user" /grant administrators:F /t
Thank you very much in advance for helping.
So I have hundreds of files and folders from which I'd like to remove the user: C850-108.
I can do this using Windows interface, but it'd take me days to do it in every file.
The reason I'd like to do this is because Cobian Backup tool can't have access to this files (Permission denied) and I think that user is the problem.
So I have Cygwin (bash) an PowerShell to help me in this tedious task.
I attach 3 screenshots:
Windows Security tab
PowerShell output of the command get-acl | format-list
Cygwin output of getfacl
I'm more experienced with bash, so I tried adding an user like this:
setfacl.exe -m u:rafaelgp:rwx myfile
Which apparently did nothing, but when I check with PowerShell, I saw that it actually worked and added a new user (rafaelgp) with the specified permissions. You can see this in the screenshots. So after this I lost some trust in Cygwin.
I've also tried deleting the user like this:
setfacl.exe -d u:C850-108 myfile
But I get the following message:
setfacl: illegal acl entries
So what can I do? As I said, I'm happy trying anything using bash or PowerShell.
Cheers!
UPDATE:
Screenshot of Musaab Al-Okaidi solution. There seems to be a problem with the '$file' parameter
The simplest way would arguably be icacls:
icacls file /remove C850-180
You can't remove permissions that were inherited from the parent folder with this, though. I suspect that this is the reason why setfacl failed. Unfortunately the inheritance information is suppressed when you pipe the output of Get-Acl into Format-List. Try this instead:
Get-Acl file | % { $_.Access } | ? { $_.IdentityReference -match 'C850-180' }
The IsInherited property will show you whether or not the ACL is inherited. If the ACL is inherited, you have to disable inheritance first before you can remove an ACL:
icacls file /inheritance:d
icacls is available since Windows Server 2003 SP2.
Update:
You can apply this recursively to a folder tree by adding the option /t:
icacls C:\some\folder\* /t /inheritance:d
icacls C:\some\folder\* /t /remove C850-180
Be advised, though, that it's not a good idea to recursively disable inheritance as it will make managing permissions a nightmare. Depending on your folder structure it might be better to simply remove inheritance and that particular ACE from the parent folder:
icacls C:\some\folder /inheritance:d
icacls C:\some\folder /remove C850-180
The subfolders and files will automatically inherit their parent folder's changed permissions. If necessary you can enforce that by resetting permissions on subfolders and files:
icacls C:\some\folder\* /reset /t /c
Add the following function to your shell, simply copy and paste, then you will have Remove-UserAccess as a usable Cmdlet
Function Remove-UserAccess()
{
Param
(
[Parameter(Mandatory=$true)][String]$Path,
[Parameter(Mandatory=$true)][String]$User
)
$Files = New-Object System.Collections.ArrayList
$Files.Add($Path) | Out-Null
#Add all files and folders to an array
$PathSubtree = Get-ChildItem -Path $Path -Recurse
Foreach ( $File in $PathSubtree )
{
$Files.Add($File.FullName) | Out-Null
}
# Remove access of the $User from each file in the array
Foreach ( $File in $Files )
{
$AccessRule = Get-Acl $File | % { $_.Access } | ? { $_.IdentityReference -eq $User}
IF ( $AccessRule -eq $null )
{
Write-Host "$User does not have access to $File" -ForegroundColor Yellow
}
ELSE
{
$ACL = Get-Acl $File
$ACL.RemoveAccessRule($AccessRule) | out-Null
Set-Acl -Path $File -AclObject $ACL -ErrorAction Stop
Write-Host "Permissions for $user have been removed from the following path: $File" -ForegroundColor Green
}
}
}
Execute the command as follows:
Remove-UserAccess -Path C:\temp -User RAFALAPTOP\C850-108
This will remove the access for the user from C:\temp and all sub-files and folders.