Loop through folder, delete all shortcuts and make new ones - powershell

So what my powershell script does currently is it asks for path, name of new folder and what the old one was and then it copies the old file contents and puts them in the new one.
What i want after that is to delete all shortcuts and make new ones with target of the exe in new folder and the path or "start in" to be the location of the exe
What code i have currently:
$Location = Read-Host -Prompt 'User writes loc'
Set-Location -Path $Location
$oldname = Read-Host -Prompt 'User writes old file name'
$newname = Read-Host -Prompt 'User writes new file name'
Copy-Item -Path "$Location\$oldname" -Destination "$Location\$newname" -Recurse
$folder = "$Location\$newname"
$files = Get-ChildItem -Path $folder -Include *.lnk -File -Recurse
//Here i now want to delete all the shortcuts it found, tried this 2 ways
//both dont work (inside or outside the loop)
Get-ChildItem -Recursive *.lnk | foreach { Remove-Item -Path $_.FullName }
Remove-Item '$folder\*' -Recurse -Include *.lnk
ForEach($file in $files){
//Then have path set to location where it found the shortcut/exe
//and then target the exe (idk how to get "link")
New-Item -ItemType SymbolicLink -Path "Link" -Target $file
}

Related

Create multiple directories in different folders

I want to create one folder for each preselected *.mkv-file in the corresponding subfolder, named after that *.mkv-file, e.g.:
Z:\1\1.mkv; Z:\2\2.mp4; Z:\3\3.mkv --> Z:\1\1 (additional folder);
Z:\1\1.mkv; Z:\2\2.mp4; Z:\3\3 (additional folder); Z:\3\3.mkv
$inputfiles = gci *.mkv -recurse
foreach ($file in $inputfiles)
{
new-item -path Z:\* -name "$($file.BaseName)" -itemtype directory
}
Problem here is, that in each subfolder all of the directories are created, not just the corresponding one.
I also tried -path $inputfiles but got an error message.
Any help is appreciated
The main problem is that you have added \* after the path for the New-Item.
Try:
Get-ChildItem -Filter '*.mkv' -File -Recurse | ForEach-Object {
# construct the path for the (new) subfolder
$targetFolder = Join-Path -Path 'Z:\' -ChildPath $_.BaseName
# create a new directory if not already existed
$null = New-Item -Path $targetFolder -ItemType Directory -Force
# if you want the .mkv file to be moved to that new directory, uncomment the line below
# $_ | Move-Item -Destination $targetFolder
}
The -Force switch on the New-Item line ensures it either creates a new directory or returns the folder object of an existing one without error messages.

Moving contents of a folder up one level based on folder name

I have a directory of information that is separated into document numbers so each folder that contains documents starts with DOC-######-NameOfDocument. The thing I am trying to do is create a PowerShell script that will search a directory for any folders with a specified document number and then take the contents of that folder, move it up one level, and then delete the original folder (which should now be empty).
Below is the closest I have gotten to my intended result.
$Path = "filepath"
$Folders = Get-ChildItem -Filter "DOC-#####*" -Recurse -Name -Path $Path
$companyID = "######"
foreach ($Folder in $Folders){
$filepath = $Path + $Folder
$Files = Get-ChildItem -Path $filepath
$imagesourc = $filepath + $companyID
$imageDest = $filepath.Substring(0, $filepath.LastIndexOf('\'))
if (Test-Path -Path $imagesourc){
Copy-Item -Path $imagesourc -Destination $imageDest -Recurse
}
foreach ($File in $Files){
$Parent_Directory = Split-Path -Path $File.FullName
$Destination_Path = $filepath.Substring(0, $filepath.LastIndexOf('\'))
Copy-Item -Path $File.FullName -Destination $Destination_Path -Recurse
if ($null -eq (Get-ChildItem -Path $Parent_Directory)) {
}
}
Remove-Item $filepath -Recurse
}
This does what I need but for whatever reason I can't Devine, it will not work on .HTM files. Most of the files I am moving are .html and .htm files so I need to get it to work with .htm as well. The files with .HTM will not move and the folder won't be deleted either which is good at least.
Try using this:
$ErrorActionPreference = 'Stop'
$fileNumber = '1234'
$initialFolder = 'X:\path\to\folders'
$folders = Get-ChildItem -Path $initialFolder -Filter DOC-$fileNumber* -Force -Directory -Recurse
foreach($folder in $folders)
{
try
{
Move-Item $folder\* -Destination $folder.Parent.FullName
Remove-Item $folder
}
catch [System.IO.IOException]
{
#(
"$_".Trim()
"File FullName: {0}" -f $_.TargetObject
"Destination Folder: {0}" -f $folder.Parent.FullName
) | Out-String | Write-Warning
}
catch
{
Write-Warning $_
}
}
Important Notes:
Move-Item $folder\* will move all folder contents recursively. If there are folders inside $folder, those will also be moved too, if you want to target folders which only have files inside, an if condition should be added before this cmdlet.
Try {...} Catch {...} is there to handle file collision mainly, if a file with a same name already exists in the parent folder, it will let you know and it will not be moved nor will the folder be deleted.
-Filter DOC-$fileNumber* will capture all the folders named with the numbers in $fileNumber however, be careful because it may capture folders which you may not intent to remove.
Example: If you want to get all folders containing the number 1234 (DOC-12345-NameOfDocument, DOC-12346-NameOfDocument, ...) but you don't want to capture DOC-12347-NameOfDocument then you should fine tune the filter. Or you could add the -Exclude parameter.
-Force & -Directory to get hidden folders and to target only folders.

Unzip archive zip file into folder with same name as archive zip file

I am able to successfully unzip a zipped file using a Powershell script as follows:
$filePath = "s:\Download Data Feed\"
$zip = Get-ChildItem -Recurse -Path $filePath | Where-Object { $_.Extension -eq ".zip" }
foreach ($file in $zip) {
Expand-7Zip -ArchiveFileName $file -Password "Password" -TargetPath $filePath
}
Read-Host -Prompt "Press Enter to exit"
The zip file are csv files. But what I would like is to unzip the csv file in a folder of the same name as the zip file itself (just as when you right click the zipped file you can choose to extract it as the file itself or to a folder of the same name as the zip file). I've tried looking at the switches for Expand-7Zip command but can't find any.
Thanks
You could do something like the following (I cannot test with Expand-7Zip):
$filePath = "s:\Download Data Feed\"
$zip = Get-ChildItem -File -Recurse -Path $filePath | Where-Object { $_.Extension -eq ".zip" }
foreach ($file in $zip) {
$target = Join-Path $filePath $file.BaseName
if (!(Test-Path $target -PathType Container)) {
$null = New-Item -ItemType Directory -Path $target
}
Expand-7Zip -ArchiveFileName $file -Password "Password" -TargetPath $target
}
Explanation:
Each FileInfo object contained in the $zip collection has a property, BaseName, which is the name of the file without the extension.
Join-Path is used to join a path with a child path. The child path here will be the BaseName value of $file during each iteration.
Test-Path is used to verify if a path already exists. If the $target path does not exist, it will be created due to the New-Item command.
Another approach to getting the target folder path is to simply use a regex replace, which is likely more efficient:
$target = $file.FullName -replace '\.zip$'

Copy first image file from subfolders into parent and rename

Inside a specific folder I have a few sub-folders, in each are stored image files.
I would like to copy the first image file from each sub-folder into the parent and rename it to the folder's name that it belongs.
I managed to write the following script with the information from several other questions on the site but there is something that is not working as expected. Running the script doesn't copy/rename any file.
$Root = (Get-Item -Path '.\' -Verbose).FullName #'
$Folders = Get-ChildItem -Path $Root -Directory
$Image = Get-ChildItem -Name -Filter *.* | Select-Object -First 1
Foreach($Fld in $Folders)
{
Copy-Item -Path "$($Fld.FullName)\$Image" -Destination "$Root\$($Fld.Name).jpeg"
}
Read-Host -Prompt "Press Enter to exit"
I want to be able to run the script from any folder, the paths must be relative and not absolute/hardcoded. I think the $Root variable achieves that purpose.
The sub-folders only contain image files, the filter *.* in the $Image Get-ChildItem is fine for the purpose as it will always pick an image. However the Copy-Item command will copy it with the jpeg extension, is it possible to check the image file extension and copy/rename accordingly? Perhaps with some If statements?
You're mistakenly getting the $image in your $root-directory since you are using the get-childitem without any -Path parameter. For your purpose you need Foreach $Fld (folder) seperately:
$Root = (Get-Item -Path '.\' -Verbose).FullName #'
$Folders = Get-ChildItem -Path $Root -Directory
Foreach($Fld in $Folders)
{
$Image = Get-ChildItem -Path $Fld -Name -Filter *.* | Select-Object -First 1
Copy-Item -Path "$($Fld.FullName)\$Image" -Destination "$Root\$($Fld.Name).jpeg"
}
Read-Host -Prompt "Press Enter to exit"
Here is you code a little shortened:
$Folders = Get-ChildItem -Directory # Without -path you are in the current working directory
Foreach($Fld in $Folders)
{
$Image = Get-ChildItem -Path $Fld -Filter *.* | Select-Object -First 1 # Without the -name you get the whole fileinfo
Copy-Item -Path $Image.FullName -Destination "$PWD\$($Fld.Name)$($Image.Extension)" # $PWD is a systemvariable for the current working directory
}
Read-Host -Prompt "Press Enter to exit"
You could be even bolder as the FullName of the folder contains the path:
Copy-Item -Path $Image.FullName -Destination "$($Fld.FullName)$($Image.Extension)"

Test and Create File path

The basic idea:
Mirror the directory structure of the target path
Search the target path for files and folders of a certain age and create a text file with all the paths.
Read the previous text file and copy the contents of the different paths to a new drive location.
Script 1 - Mirror the directory structure of the target path from drive to the next. This I feel like I have working pretty decently.
$target = Read-Host "What is the target path?"
$destination = "Z:\This\Is\The\Destination"
Copy-Item $target -Filter {PSIsContainter} -Recurse -Destination $destination -Force
Script 2 - Is used to look through the $target path and looks for files and folders that are -ge -le -eq a lastwritetime, then outputs the locations in a text file.
$path = read-host "What path would you like to search?"
$daysOLD = read-host "How many days old should the files I'm looking for be?"
$outfile = "C:\locationOFtheTEXTfile\ReadThis.txt"
$today = Get-Date
$targetdate = $today.AddDays(-$daysOLD).ToString('MM-dd-yyyy')
$files = Get-ChildItem $path -Recurse| Where-Object {$_.lastwritetime.ToString('MM-dd-yyyy') -le $targetdate} | ForEach-Object {$_.fullname}| out-file $outfile
Script 3 - Is where I am having an issue. I know that I can use Get-Content and point to the location of the text file. What I have a hard time with is having the script read the file, test the path, and not create duplicates in the $destination.
Since I mirrored the directory structure with the first path, I just need the third script to move files to their appropriate folders on the new drive.
$dest = "Z:\This\Is\The\Destination"
$safe = Get-Content "C:\locationOFtheTEXTfile\ReadThis.txt"
$safe | ForEach-Object{
#find drive-delimeter
$first=$_.IndexOf(":\");
if($first -eq 1){
#stripe it
$newdes=Join-Path -Path $dest -ChildPath #($_.Substring(0,1)+$_.Substring(2))[0]
} else {
$newdes=Join-Path -Path $des -ChildPath $_
}
$folder = Split-Path -Path $newdes -Parent
$err=0
#check if folder exists"
$void=Get-Item $folder -ErrorVariable err -ErrorAction SilentlyContinue
if($err.Count -ne 0){
#create when it doesn't
$void=New-Item -Path $folder -ItemType Directory -Force -Verbose
}
$void=Copy-Item -Path $_ -destination $newdes -Recurse -Container -Force -Verbose
}
write-host "Doomsday =("
This script was taken from the web and I haven't had a chance to figure it's parts and pieces for myself. I know that sound pathetic but I don't feel like trying to reinvent the wheel is necessary.