I have some shared files set up for me for testing purposes, on a Windows Server 2016.
My given task is to get all the users, and their access rights to there shared files/folders.
I get the shared files with
Get-SmbShare | Select-Object -Property Name, Path
What I think I should do, is passing each share's path into
Get-Acl
So I came up with this:
$shares = Get-SmbShare | Where-Object Name -notlike "*$" | Select-Object Name
foreach ($share in $shares){
$path = "\\$env:COMPUTERNAME\" + $share.Name.ToString()
$FolderPath = dir -Directory -Path $path -Recurse -Force
Foreach ($Folder in $FolderPath) {
$Acl = Get-Acl -Path $Folder.FullName
foreach ($Access in $acl.Access)
{
$Folder.FullName;
$Access.IdentityReference;
$Access.FileSystemRights;
$Access.IsInherited
}
}
}
My question is: How could I format this output, so it looks readable, and/or is there a simpler, maybe cleaner to do what I intend to do?
Related
I am trying to come up with a script to copy folders from one server to another. I might be going about this wrong, but I'm try to copy the directories from one server into an array, copy the directories from the second server into an array, compare them and then create the folders needed in the server that doesn't have them:
[array]$folders = Get-ChildItem -Path \\spesety01\TGT\TST\XRM\Test -Recurse -Directory -Force -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
[array]$folders2 = Get-ChildItem -Path \\sutwove02\TGT\TST\XRN -Recurse -Directory -Force -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName
$folders | ForEach-Object {
if ($folders2 -notcontains "$_") {
New-Item "$_" -type directory
}
}
The issue is that the "$_" (in the ForEach loop)refers to the server in "$folders" and when I run the script, I get an error that the folder already exists. Is there some way to specify to copy the folders to the new server? I accept that my approach might be completely off on this and I might be making it harder than it needs to be.
<#
.SYNOPSIS
using path A as reference, make any sub directories that are missing in path B
#>
Param(
[string]$PathA,
[string]$PathB
)
$PathADirs = (Get-ChildItem -Path $PathA -Recurse -Directory).FullName
$PathBDirs = (Get-ChildItem -Path $PathB -Recurse -Directory).FullName
$PreList = Compare-Object -ReferenceObject $PathADirs -DifferenceObject $PathBDirs.replace($PathB,$PathA) |
Where-Object -Property SideIndicator -EQ "<=" |
Select-Object -ExpandProperty 'InputObject'
$TargetList = $PreList.Replace($PathA,$PathB)
New-Item -Path $TargetList -ItemType 'Directory'
Okay so we are setting up a card access system that looks at the Active Directory Users thumbnailPhoto attribute. I am creating an audit system that exports the Users and compares them with the JPG images. If the image exists but there isn't a correlating user, it moves the image into an archive to be reviewed. The goal is to remove old employee photos into a folder incase of later hire. I can't get the image to move into another folder if it matches a name in the CSV. Here is the entire code:
<#Write Users to a CSV File #>
$adUsers = get-aduser -filter * -properties displayname | select displayname | export-csv -path PATHWAY.CSV -notypeinformation -encoding unicode
$keepImages = #()
$removeImages = #()
[System.Collections.ArrayList]$arrA = (Get-Childitem -Filter * -path PATHWAY).Basename
[System.Collections.ArrayList]$arrB = Get-Content PATHWAY.CSV
foreach ($itemA in $arrA) {
if ($arrB -ne $itemA) {
$arrB.Remove($itemA)
$removeImages += $itemA }}
$removeImages |out-file -FilePath PATH.csv
<# PUT THE FILES INTO AN ARCHIVE #>
--Cant get it to move here, note I am brand new to Powershell, its not like python at all--
You can try this. I have added inline comments to hopefully explain how it works:
$ImagesFolder = 'D:\UserImages'
$OldUserImages = 'D:\UserImages\OldUsers'
# test if the path to move old images exists and if not create it
if (!(Test-Path -Path $OldUserImages -PathType Container)) {
$null = New-Item -Path $OldUserImages -ItemType Directory
}
# get a list of ADUser display names
$adUsers = Get-ADUser -Filter * -Properties DisplayName | Select-Object -ExpandProperty DisplayName
# get an array of FileInfo objects of the user images currently in the $ImagesFolder.
# filter out only those that do not have a basename that correlates to any of the users DisplayName
# and move these to the $OldUserImages folder.
# Tip: if for instance all are of type JPG, add -Filter '*.jpg' to the Get-ChildItem cmdlet.
Get-ChildItem -Path $ImagesFolder -File |
Where-Object { $adUsers -notcontains $_.BaseName } |
Move-Item -Destination $OldUserImages -Force
If you want to keep track of the images you have moved, you can extend the above like:
$moved = Get-ChildItem -Path $ImagesFolder -File |
Where-Object { $adUsers -notcontains $_.BaseName } |
ForEach-Object {
$file = $_.FullName
$_ | Move-Item -Destination $OldUserImages -Force
[PsCustomObject]#{
'File' = $file
'MovedTo' = $OldUserImages
}
}
# show result on screen
$moved | Format-Table -AutoSize
# write to CSV file
$out = '{0:yyyy-MM-dd}_MovedImages.csv' -f (Get-Date)
$moved | Export-Csv -Path (Join-Path -Path $ImagesFolder -ChildPath $out) -NoTypeInformation
I want to remove ALL AD User objects from a directory/folder security.
So, this maybe a stupid post and i appologise if it is...but basically i want to recurse through a directoery and remove all user objects from permissions. Folder permissions should be secured using groups, buit occasionally there are user onjects directly being added to folders breaking the rules. I've got a simple little script that works great for specific users, but i'm having trouble setting this to use a variable, eg all domain user accounts. If i specify the $user variable as an AD search for instance it just doesnt work, eg $USER = 'Get-ADuser -filter * -Server 'DOMAIN -properties SamAccountName | Select SamAccountName
I'm assumign this doesnt like the variable field set this way. Any help or advise much appreciated. Thanks.
$filepath = 'C:\Temp\ACLTesting'
$user = 'DOMAIN\USER'
Get-ChildItem $filePath -Recurse -Directory | ForEach-Object {
$acl = Get-Acl -Path $_.FullName
$acl.Access | Where-Object {
$_.IdentityReference.Value -eq $user
} | ForEach-Object {
$acl.RemoveAccessRule($_) | Out-Null
}
Set-Acl -Path $_.FullName -AclObject $acl
}
Unfortunately still cant get this to work using user variables... am i missing something or is this not a possible function? Thanks....
Putting this to one side for now as still cant get it to work and other things have cropped up to look at. Will revisit this at somepoint though. Any suggestions always welcome. Thanks.
Slightly modifying what you posted, try this …
$filepath = 'C:\Temp\ACLTesting'
$DomainUsers = (Get-ADUser -Filter *).SamAccountName
ForEach ($DomainUser in $DomainUsers)
{
Get-ChildItem $filePath -Recurse -Directory |
ForEach-Object {
$acl = Get-Acl -Path $_.FullName
$acl.Access |
Where-Object {
$_.IdentityReference.Value -eq $DomainUser
} |
ForEach-Object {
$acl.RemoveAccessRule($_) | Out-Null
}
Set-Acl -Path $_.FullName -AclObject $acl
}
}
I need to create a script to iterate through a list of user samaccountnames and identify network directories matching their samaccountname on the network. It doesn't seem to work though. Users home folders on the network use their samaccountname in the path. Here is what I have so far:
$userList = "C:\Users\sfp01\My
Documents\Data_Deletion_Testing\User_SamAccountName.csv"
$userDirectory = foreach ($user in $userList)
{
Get-ChildItem -Path "\\ceoii\" -Directory -Recurse | ? {}
}
Export-Csv -Path "C:\Users\sfp01\My
Documents\Data_Deletion_Testing\User_Directory.csv"
First, you need to import the csv as your first line just saves the location of the file in the variable rather than the contents of the file.
Second, you didn't provide the column name of the csv file that contains the user's saMAccountName. You'll need to set up your Where-Object to filter using that information. I am using -match on saMAccountName, but edit this to reflect your requirements.
And I don't think that \\servername\ isn't a valid share name, it should be a share like \\servername\share\ If you want to get all the shares from a server you could enumerate them with something like this invoke-command -ComputerName ceoii -ScriptBlock {Get-SmbShare}
You also probably want to only pull the list of folders once and then filter for each user.
Lastly, you save the information in $userDirectory so you'll want to pipe that information into your export-csv.
$userList = Import-CSV 'C:\Users\sfp01\My Documents\Data_Deletion_Testing\User_SamAccountName.csv'
$folders = Get-ChildItem -Path "\\ceoii\sharename" -Directory -Recurse
$userDirectory = foreach ($user in $userList) {
$folders | Where-Object {$_.name -match $user.saMAcountName}
}
$userDirectory | Export-Csv -Path 'C:\Users\sfp01\My Documents\Data_Deletion_Testing\User_Directory.csv'
More efficient than that would be to use -in or -contains if you know that the folder names exactly match.
$folders = Get-ChildItem -Path "\\ceoii\sharename" -Directory -Recurse
$userList = Import-CSV 'C:\Users\sfp01\My Documents\Data_Deletion_Testing\User_SamAccountName.csv' |
Select-Object -ExpandProperty saMAccountName
$folders |
Where-Object {$_.name -in $userList} |
Export-Csv -Path 'C:\Users\sfp01\My Documents\Data_Deletion_Testing\User_Directory.csv'
At work we have a folder with lots of subfolders named like "MeyerS". (Lastname and the first letter of surname)
When I take a look at Get-ChildItem $path | Get-Acl the username equals the subfolder-name. But there is also a "SCHUELER\" in front of "MeyerS". This is what the output looks like a.e.: SCHUELER\MeyerS Allow Write, ReadAndExecute, Synchronize
Some subfolders don't have this kind of username. Now I want to output all these subfolders without this username- "combination".
With my first codesnippet I get all of them, but I really just want these specific ones.
I checked some similar questions, and found something. I modified it, but it shows all subfolders just without SCHUELER\MeyerS. I think I just need a small push to the right way.
The code so far:
$path = "R:\HOME"
$folders = Get-ChildItem $path | where {$_.psiscontainer}
foreach ($folder in $folders){
$domain = "domname"
$aclname = "ACLname"
$aclfullname ="$domain\$aclname"
Get-Acl | select -ExpandProperty Access | where {$_.identityreference -notcontains $aclfullname}
Write-Host $folder.FullName}
Short note: I tried a lot of variations with -noteq or -notlike.
What do I have to change?
If there is already an answer I really didn't know.
Sometimes it's really hard to enunciate yourself in another language. I hope you get my point.
Thanks.
$path = "R:\HOME"
$folders = Get-ChildItem $path | where {$_.psiscontainer}
foreach ($folder in $folders)
{
$domain = "domname"
$aclname = "ACLname"
$aclfullname ="$domain\$aclname"
$FoldersWithAclFullName = $null
$FoldersWithAclFullName = Get-Acl -Path $Folder `
| Select-Object -ExpandProperty Access `
| Where-Object -Property IdentityReference -ne -Value $aclfullname
if ( -not $FoldersWithAclFullName )
{
Write-Host $folder.FullName
}
}