Theldron Posted February 2, 2024 Posted February 2, 2024 (edited) Hi all, Hope you are well. Need some guidance on this, as sometimes for exams/taster days, I need to copy folders/files, to multiple folders for users to access exam worksheets etc. Is there a way to script this rather than having to copy and paste multiple times? It can be 100s of user home folders that I need to copy to, so having the destination in a text/csv file would be the best option? Thanks Edited February 2, 2024 by Theldron
dmj Posted February 2, 2024 Posted February 2, 2024 Hi all, It can be 100s of user home folders that I need to copy to, so having the destination in a text/csv file would be the best option? Thanks Querying the user directory dynamically would be the best option 1
localzuk Posted February 2, 2024 Posted February 2, 2024 I'd do this by using PowerShell to grab the list of users and their directories, then iterate through them to copy the files where you want them. 1
mavhc Posted February 2, 2024 Posted February 2, 2024 Set-StrictMode -Version 2.0 function copy-item-no-overwrite { Param ( $sourcedir, $destinationdir, $filename ) #write-output "source" $sourcedir #write-output "destination", $destinationdir #write-output "filename", $filename $destinationpath = $destinationdir + "\" + $filename $sourcepath = $sourcedir + "\" + $filename if (-not (test-path -path $destinationpath)) { write-output "file doesn't exist", $destinationpath copy-item $sourcepath -Destination $destinationpath } } write-output $env:userprofile $pupils = Import-CSV -Path "student_list.csv" foreach ($pupil in $pupils ) { $name = $pupil.'Name' $destination = "somedrive\Pupils\"+$name write-output $destination if (-not (test-path -Path $destination)) { write-output "new!" copy-item -recurse "$Env:userprofile\somefolder" -Destination $destination } } This will copy a folder of files, to somewhere based on pupil name/username/etc, but only if that folder doesn't already exist 1
jthompson Posted February 2, 2024 Posted February 2, 2024 Here's a PowerShell script that uses a CSV of destination folders. <# .DESCRIPTION Script to copy files to a list of destination folders. .PARAMETER Source The path to source file(s) to copy. .PARAMETER CSV The path to a CSV file containing the paths of destination folders. The CSV file must include a column named 'FolderPath'. .EXAMPLE CopyToFolders.ps1 -Source foo.txt -CSV destFolders.csv Copy foo.txt to each folder listed in the CSV file destFolder.csv .EXAMPLE CopyToFolders.ps1 -Source C:\Test -CSV destFolders.csv Copy the folder "C:\Test" and its contents to each folder listed in the CSV file destFolder.csv .EXAMPLE CopyToFolders.ps1 -Source C:\Test\* -CSV destFolders.csv Copy only the contents of the "C:\Test" folder to each folder listed in the CSV file destFolder.csv #> param( [Parameter(Mandatory)] [string] $Source, [Parameter(Mandatory)] [string] $CSV ) # Import folder paths from CSV. $destFolders = Import-Csv -Path $CSV # Process the list of folders. foreach ($destFolder in $destFolders) { # Check that the folder exists. if (Test-Path $destFolder.FolderPath) { # Folder exists. Copy source files to folder. Write-Host "Copying to folder: $($destFolder.FolderPath)" Copy-Item -Path $Source -Destination $destFolder.FolderPath -Recurse } else { Write-Host "Folder not found: $($destFolder.FolderPath)" } } 1
jthompson Posted February 2, 2024 Posted February 2, 2024 To compliment that, you might also want a script that empties a list of folders. We use this when clearing out exam user folders. <# .DESCRIPTION Script to empty a set of folders. .PARAMETER CSV The path to a CSV file containing the paths of folders to be emptied (the folder itself is not to be deleted). The CSV file must include a column named 'FolderPath'. .EXAMPLE EmptyFolders.ps1 -CSV folders.csv Empty each of the folders listed in folders.csv #> param( [Parameter(Mandatory)] [string] $CSV ) # Import folder paths from CSV. $folders = Import-Csv -Path $CSV # Process the list of folders. foreach ($folder in $folders) { # Check that the folder exists. if (Test-Path $folder.FolderPath) { # Folder exists. Recursively remove child items. Write-Host "Emptying folder: $($folder.FolderPath)" Get-ChildItem -Path $folder.FolderPath -Recurse | Remove-Item -Force -Recurse } else { Write-Host "Folder not found: $($folder.FolderPath)" } } 1
dmj Posted February 2, 2024 Posted February 2, 2024 I'd do this by using PowerShell to grab the list of users and their directories, then iterate through them to copy the files where you want them. This is the correct way to do this; it lends itself better to automation/self service and it is less error prone. All major directory services have an api or cli integration so CSV should be a thing of the past now. 1
mavhc Posted February 2, 2024 Posted February 2, 2024 Something like $ldappath = 'LDAP://OU=Pupils,DC=school,DC=local' write-output $ldappath $DirSearcher = New-Object DirectoryServices.DirectorySearcher([adsi]$ldappath) $DirSearcher.Filter = '(&(objectClass=person)(objectClass=user)(sAMAccountName=exam*))' $users = $DirSearcher.FindAll().GetEnumerator() | ForEach-Object { $_.Properties.name } 2
jthompson Posted February 2, 2024 Posted February 2, 2024 (edited) But you may still need a CSV to provide a list of usernames or OUs. For realtively simple jobs (e.g. a set of exam resource files into a couple of dozen exam user areas), a script that doesn't involve AD will be nice and simple/fast. But yes, for non-trivial lists of paths, programmatically fetching those from AD would be wise. Edited February 2, 2024 by jthompson 1
dmj Posted February 2, 2024 Posted February 2, 2024 (edited) The next step would be to integrate it into a system so that you can offload the script for a user to run, this sort of task shouldn't be for IT to do - once you've got a method to run it. Edited February 2, 2024 by dmj 1
altecsole Posted February 2, 2024 Posted February 2, 2024 Can't you just have a read-only share that gets mapped at logon? Drop the files in there and tell them to copy them to their home folder to work on them? 2
dhicks Posted February 2, 2024 Posted February 2, 2024 The next step would be to integrate it into a system so that you can offload the script for a user to run That's what one of my projects does: https://github.com/dhicks6345789/web-console Can sit behind a simple proxy server or a snazzy ingress-with-authentication system such as Cloudflare Zero Trust or Ngrok. Provides a simple web-based interface for the user - very simple, a large green button with "Run" on it. 2
dmj Posted February 2, 2024 Posted February 2, 2024 That's what one of my projects does: https://github.com/dhicks6345789/web-console Can sit behind a simple proxy server or a snazzy ingress-with-authentication system such as Cloudflare Zero Trust or Ngrok. Provides a simple web-based interface for the user - very simple, a large green button with "Run" on it. Nice. You can get similar functionality in CI/CD tooling. We're using Jenkins for this sort of thing. 2
Theldron Posted February 14, 2024 Author Posted February 14, 2024 Brilliant thanks for your help all.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now