Rename Folders After Copy - powershell

I'm having problems after a folder is copied to a different location, I need to rename the folders in the directory to remove ".deploy" from the end, but I get the following error below. I have Googled around for PowerShell admin permissions, but cannot seem to find a 'catch-all' for my scenario.
Get-Content : Access to the path 'C:\OldUserBackup\a.deploy' is denied.
At C:\PSScripts\DesktopSwap\TestMergeDir.ps1:28 char:14
+ (Get-Content $file.PSPath) |
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\OldUserBackup\a.deploy:String) [Get-Content], UnauthorizedAccessException
+ FullyQualifiedErrorId : GetContentReaderUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetContentCommand
Here is what I have:
$UserName = [Environment]::UserName
$CurrUser = [Environment]::UserName + '.deploy'
$OldUserDir = 'C:\OldUserBackup'
$CurrDate = Get-Date -format G
$PathExist = Test-Path $OldUserDir
if ($PathExist -eq $true) {
#Copy Desktop, Downloads, Favorites, Documents, Music, Pictures, Videos
Copy-Item -Path $OldUserDir -Destination C:\Users\$UserName\Desktop\CopyTest -Recurse -Force
$configFiles = Get-ChildItem $OldUserDir *.deploy -rec
foreach ($file in $configFiles) {
(Get-Content $file.PSPath) |
Foreach-Object { $_ -replace ".deploy", "" } |
Set-Content $file.PSPath
}
}

You should use the -Directory switch on the Get-ChildItem cmdlet to only get directories. Then use the Rename-Item cmdlet to rename the folders. I use the -replace function with a simple regex to get the new folder name:
$deployFolders = Get-ChildItem $OldUserDir *.deploy -rec -Directory
$deployFolders | Foreach {
$_ | Rename-Item -NewName ($_.Name -replace ('\.deploy$') )
}
You don't even have to use the Foreach-Object cmdlet (Thanks to AnsgarWiechers):
Get-ChildItem $OldUserDir *.deploy -rec -Directory |
Rename-Item -NewName { $_.Name -replace ('\.deploy$') }

Related

Powershell - Rename File and Upload

I have the below script which is working fine for what we need thus far however running into an error as the file names have changed.
With the below script it is providing a Cannot Find Path error as the filenames have changed.
Where am i going wrong with this one?
## Add ShareFile PowerShell Snap-in
Add-PSSnapin ShareFile
## Create new authentiation file
#New-SfClient -Name "C:\Sharefile\SVCACC.sfps" -Account midl
## Variables ##
$OutputAppReqFID = "fo4a3b58-bdd6-44c8-ba11-763e211c183f"
$Project = 'M000'
$LocalPath = "\\file.server.au\$project\DATA\DATA CUSTODIAN\OUTPUT\"
$sfClient = Get-SfClient -Name C:\sharefile\SVCACC.sfps
$OutputAppReqFID_URL = (Send-SfRequest $sfClient -Entity Items -id $OutputAppReqFID).Url
## Create PS Drive ##
New-PSDrive -Name "sfDrive-$($project)" -PSProvider ShareFile -Client $sfClient -Root "\" -RootUri $OutputAppReqFID_URL
## Copy all files from folders to ShareFile
foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force | Where-Object {$_.Mode -ne "d-----"} | Select FullName -ExpandProperty FullName) {
Get-ChildItem $file -Recurse | Rename-Item -NewName { $_.Directory.Name+'_'+$_.Name}
Copy-SfItem -Path $file -Destination "sfDrive-$($project):"
#remove-item $file
}
<## Remove all folders from UNC directory
foreach ($folder in Get-childitem -Path $LocalPath -Recurse | Where-Object {$_.Mode -eq "d-----"} | Select-Object -ExpandProperty FullName) {
remove-item $folder
}
#>
## Remove PS Drive ##
Remove-PSDrive "sfdrive-$($project)"
Error recieved is below:
Copy-SfItem : Cannot find path '\\file.server.au\M000\DATA\DATA CUSTODIAN\OUTPUT\New Text Document.txt' because it does not exist.
At line:43 char:6
+ Copy-SfItem -Path $file -Destination "sfDrive-$($project):"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (\\file.serve...xt Document.txt:String) [Copy-SfItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,ShareFile.Api.Powershell.CopySfItem
The problem is that you are renaming $file and then trying to Copy-SfItem -Path $file in the very next line. This reference to $file is still pointing to the old name before the rename. You need to instead capture the path to the newly renamed filepath and then reference that in your Copy-SfItem command
foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force |
Where-Object { $_.Mode -ne 'd-----' } |
Select-Object -ExpandProperty FullName) {
# capture reference to the new file name by using -PassThru switch with
# the Rename-Item cmdlet and saving in a variable ($renamedFile)
$renamedFile = Get-ChildItem $file -Recurse |
Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name } -PassThru
# Now we copy using our $newFile reference
Copy-SfItem -Path $renamedFile -Destination "sfDrive-$($project):"
# followed by removing the file if needed
# remove-item $renamedFile
}
This can be cleaned up some as well.
Adding the -File switch to Get-ChildItem will give us only files removing the need for | Where-Object {$_.Mode -ne "d-----"}
Taking off the | Select-Object -ExpandProperty FullName from the end of the foreach will eliminate the need to calling Get-ChildItem again in the first foreach loop.
foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force -File ) {
# capture reference to the new file name by using -PassThru switch with
# the Rename-Item cmdlet and saving in a variable ($newFile)
$renamedFile = $file | Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name } -PassThru
# Now we copy using our $newFile reference
Copy-SfItem -Path $renamedFile -Destination "sfDrive-$($project):"
# followed by removing the file if needed
# remove-item $renamedFile
}
Updates based on your comments
foreach ($file in Get-ChildItem -Path $LocalPath -Recurse -Force -File ) {
$file = if ($file.Directory.FullName -ne $LocalPath) {
# capture reference to the new file name by using -PassThru switch with
# the Rename-Item cmdlet and saving in a variable ($file)
$file | Rename-Item -NewName { $_.Directory.Name + '_' + $_.Name } -PassThru
}
else {
#Pass thru $file with no changes
$file
}
# Now we copy using our $file reference
Copy-SfItem -Path $file -Destination "sfDrive-$($project):"
# followed by removing the file if needed
# remove-item $file
}

Powershell error when deleting old files and folders

I'm trying to delete some old files in an archive folder and my script works fine until it gets to the last section where it removes the empty folders (testing using -whatif initially). I get the following error:
Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\ArchiveDelete.ps1:13 char:39
+ $dirs | Foreach-Object { Remove-Item <<<< $_.fullname -whatif }
+ CategoryInfo : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveItemCommand
Tried to find a suitable answer on here but can't find a solution (I know I may be using an older version of Powershell)
#Days older than
$HowOld = -900
#Path to the root folder
$Path = "C:\SharedWorkspace\ArchiveDSAgile"
#Deletion files task
get-childitem $Path -recurse | where {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force -whatif}
#Deletion empty folders task
do {
$dirs = gci $Path -recurse | Where { (gci $_.fullName -Force).count -eq 0 -and $_.PSIsContainer } | select -expandproperty FullName
$dirs | Foreach-Object { Remove-Item $_ -whatif }
} while ($dirs.count -gt 0)
None of your loops are necessary.
You can feed the output of Where-Object right into Remove-Item
$AgeCap = (Get-Date).AddDays(-900)
$Path = "C:\SharedWorkspace\ArchiveDSAgile"
Get-ChildItem $Path -Recurse -File | Where-Object LastWriteTime -lt $AgeCap | Remove-Item -WhatIf
The -File parameter for Get-ChildItem available in PowerShell 3.0 (I believe) and higher. The Workaround for PowerShell 2.0 would be checking against $_.PSIsContainer in Where-Object, as you did in your sample code.
Finally got it working:
#Days older than
$HowOld = -900
#Path to the root folder
$Path = "C:\SharedWorkspace\ArchiveDSAgile"
#Deletion files task
get-childitem $Path -recurse | where {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force -whatif}
#Deletion empty folders task
Get-ChildItem $Path -Recurse | Where-Object {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not !$_.psiscontainer} | Remove-Item -recurse -WhatIf
Thanks for your help

Error while running powershell script

I want to remove bak files after zip from all subfolder for given path, so all duplicate files with extension .bak will be removed,i run below script but getting error.
$filePath = "d:\Test\"
$Afiles = Get-ChildItem -Recurse -Path $filePath | Where-Object {$_.Extension -eq ".bak"}
$Bfiles = Get-ChildItem -Recurse -Path $filePath | Where-Object {$_.Extension -eq ".7z"}
$Alist = #()
$Blist = #()
foreach( $A in $Afiles) {
$Alist += $A.baseName
}
foreach( $B in $Bfiles) {
$Blist += $B.baseName
}
foreach($A in $Alist) {
if($Blist -contains $a)
{
rm ("$A.bak")
}
}
I am receiving below error :
Remove-Item : Cannot find path 'C:\Users\******\Desktop\master_backup_2015_08_21_013722_8370267.bak' because it does not exist.
At C:\Users\*****\Desktop\duplicatedelete1.ps1:26 char:10
+ rm <<<< ("$A.bak")
+ CategoryInfo : ObjectNotFound: (C:\Users\****....722_8370267.bak:String) [Remove-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand
You're receiving error because you're not specifying full path for rm command and PowerShell tries to delete file in your current directory.
Try this:
$Path = 'D:\Test'
Get-ChildItem -Path $Path -Recurse -Filter '*.7z' | ForEach-Object {
$BackupFile = Join-Path -Path (Split-Path $_.FullName -Parent) -ChildPath ($_.BaseName + '.bak')
if(Test-Path -Path $BackupFile){
Remove-Item -Path $BackupFile
}
}

Get-ChildItem: Illegal characters in path

I'm trying to login to multiple servers and then get list of files from those servers.
Below is my script:
$ServerName=Get-content "D:\HOMEWARE\BLRMorningCheck\Jerry\servername.txt"
foreach ($server in $ServerName)
{
$server_host=echo $server | %{$data = $_.split(";"); Write-Output "$($data[0])"}
$Targetfolder=echo $server | %{$data = $_.split(";"); Write-Output "$($data[1])"}
$Extension =#("*.log","*.txt*")
$Files = Get-Childitem $TargetFolder -Include $Extension -Recurse
echo $Files
}
When I run I debug mode I see that it really doesnt pick the files.
Error:
Get-ChildItem : Illegal characters in path.
At D:\HOMEWARE\BLRMorningCheck\Jerry\test.ps1:14 char:23
+ $Files = Get-Childitem <<<< $TargetFolder -Include $Extension -Recurse
+ CategoryInfo : InvalidArgument: (D:\HOMEWARE\BLR...ck\Jerry\Check":String) [Get-ChildItem], ArgumentException
+ FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.GetChildItemCommand
Get-ChildItem : Cannot find path 'D:\HOMEWARE\BLRMorningCheck\Jerry\"\srvparrtfh01\d$\HOMEWARE\BLRMorningCheck\Jerry\Check"' because it does not exist.
At D:\HOMEWARE\BLRMorningCheck\Jerry\test.ps1:14 char:23
+ $Files = Get-Childitem <<<< $TargetFolder -Include $Extension -Recurse
+ CategoryInfo : ObjectNotFound: (D:\HOMEWARE\BLR...ck\Jerry\Check":String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
Note: If I run it manually, example
$Files = Get-Childitem \\servername\d$\HOMEWARE\BLRMorningCheck\Jerry\Check -Include "*.log","*.txt*" -Recurse
I get the output.
As #arco444 and #PetSerAl mentioned in the comments: your path string has leading/trailing double quotes, which are invalid characters in a path. You need to remove them to make the path work as intended:
$Files = Get-Childitem ($TargetFolder -replace '^"|"$') -Include $Extension -Recurse
Of course, since your input file seems to be a some sort of CSV, you could use Import-Csv instead of reading the file with Get-Content and manually splitting the fields. That would already take care of the double quotes on file import.
$filename = 'D:\HOMEWARE\BLRMorningCheck\Jerry\servername.txt'
$extension = '*.log', '*.txt*'
Import-Csv $filename -Delimiter ';' -Header 'ComputerName', 'TargetFolder' | % {
Get-Childitem $_.TargetFolder -Include $extension -Recurse
}
This was an absolute nightmare, get-childitem cannot except a string variable if there are multiple paths.
Get-ChildItem -Path "\server1\c$\temp", "\server1\d$\temp" -File
-recurse # works
$path = '"\server1\c$\temp", "\server1\d$\temp"'; Get-ChildItem -Path "\server1\c$\temp", "\server1\d$\temp" -File
-recurse # fails with cannot find path
$path = "'"\server1\c$\temp", "\server1\d$\temp'""; Get-ChildItem -Path "\server1\c$\temp", "\server1\d$\temp" -File
-recurse # fails with illegal character message (the tick)
Any string that has multiple paths fails, however an array with += as shown below will work.
$servers = #("server1", "server2");
$partialPaths = #("\c$\temp\", "\d$\temp\");
foreach ($server in $servers)
{
$paths = #();
foreach ($partialPath in $partialPaths)
{
$paths += "\\" + $server + $partialPath;
}
}
Get-ChildItem -Path $paths -File -recurse;

replace names of all directiories and files in PS

I want to replace all space characters into "_" in names of all subfolders and files.
Unfortunately when I type:
Get-ChildItem -recurse -name | ForEach-Object { Rename-Item $_ $_.replace(" ","_") }
Error message:
Rename-Item : Source and destination path must be different. At line:1
char:60
+ Get-ChildItem -recurse -name | ForEach-Object { Rename-Item <<<< $_ $.replace(" ","") }
+ CategoryInfo : WriteError: (PATH_HERE) [Rename-Item], IOException
+ FullyQualifiedErrorId : RenameItemIOError,Microsoft.PowerShell.Commands.RenameItemCommand
How I should improve this short code?
Don't use the Name switch, it outputs only the names of the objects, not their full path. Try this:
Get-ChildItem -Recurse | `
Where-Object {$_.Name -match ' '} | `
Rename-Item -NewName { $_.Name -replace ' ','_' }
The issue here is that if there is no space in the file name the name does not change. This is not supported by Rename-Item. You should use Move-Item instead:
Get-ChildItem -recurse -name | ForEach-Object { Move-Item $_ $_.replace(" ", "_") }
Additionally, in your answer you missed the underscore in $_.replace(...) plus you where replacing spaces with an empty string. Included this in my answer.
Adding a filter worked for me:
Get-ChildItem C:\path-to-directory -Recurse -Filter *foo* | Rename-Item -NewName { $_.name -replace 'foo', 'bar'} -verbose