Error message in script - powershell

I am trying to script a solution copying some files from one location to another..
I have a list of files in a .csv format, with headers
"ParentFolder, Name, FullName, lastwritetime."
Content of file is, which has hundreds of lines, and different paths, but same drive letter:
"X:\clients\A90\201AA3.05\","2012.08 RAP Proposal.xlsm","X:\clients\A90\201AA3.05\2012.08 RAP Proposal.xlsm","20/05/2016 10:41:08"
What i would like to do is copy the above..
"X:\clients\A90\201AA3.05\2012.08 RAP Proposal.xlsm" to a new location with differnet drive, but same directory structure. So in the csv file i have the filename and path, but am unsure how to split the drive from there and make a variable.
I have a foreach loop..
$ToCopy = Import-Csv "c:\temp\log.csv"
foreach($Line in $ToCopy)
{
$FullPath = $Line.ParentFolder
$File = $Line.Name
$FullName = $Line.FullName
$file = "$FullPath\$FullName"
$DestPath = Split-Path $FullPath -NoQualifier
Copy-Item "$FullName" -Destination c:\test\$DestPath
}
Error message that i am getting is :
+ CategoryInfo : NotSpecified: (:) [Copy-Item], DirectoryNotFoundException
+ FullyQualifiedErrorId : System.IO.DirectoryNotFoundException,Microsoft.PowerShell.Commands.CopyItemCommand
Copy-Item : Could not find a part of the path 'C:\test\clients\A90\Support\_index0901\'.
At line:9 char:9
+ Copy-Item "$FullName" -Destination c:\test\$DestPath
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Copy-Item], DirectoryNotFoundException
+ FullyQualifiedErrorId : System.IO.DirectoryNotFoundException,Microsoft.PowerShell.Commands.CopyItemCommand

You get the error because the directory structure of your target path probably does not exist
To solve that you can create a 'temporary' file with New-Item ... -Force which creates the missing directories if necessary and then overwrite that file with Copy-Item like so
$ToCopy = Import-Csv "c:\temp\log.csv"
foreach($Line in $ToCopy)
{
$FullPath = $Line.ParentFolder
$File = $Line.Name
$FullName = $Line.FullName
$file = "$FullPath\$FullName"
$DestPath = Split-Path $FullPath -NoQualifier
$DestFile = c:\test\$DestPath
New-Item -ItemType File -Force $DestFile
Copy-Item "$FullName" -Destination $DestFile -Force
}

You need to create the folders before attempting to copy files in them.
Here's a way to do it, simplified from what you have, but with an added line to take care of the folders' creation.
foreach($File in $ToCopy)
{
$DestPath = Join-Path -Path 'c:\test' -ChildPath ( Split-Path $File.ParentFolder -NoQualifier )
If ( -not ( Test-Path -Path $DestPath ) ) { New-Item -Path $DestPath -Force -ItemType Directory }
Copy-Item $File.FullName -Destination $DestPath -WhatIf
}
(Be careful, I change the iteration variable from $Line to $File)

You are trying to copy files into c:\test\ directory which does not exist. Create this directory before loop:
mkdir c:\test\
or, in case directory may exist
mkdir c:\test\ -Force

Related

Export Variable contents to file

I have contents in a variable from GitHub and I want to export then to file automatically created o my local machine
I have tried to use
$FileContent | Out-File ('C:\Devjobs\clonefolder' + '\' + $repo.name + '\' + $srccontent.name)
It gives the error
Out-File : Could not find a part of the path 'C:\Devjobs\clonefolder\bct-common-devcomm-codegen-messages\BCT.Common.DevComm.CodeGen.Messages.sln'.
At line:1 char:18
+ ... lnContent | Out-File ('C:\Devjobs\clonefolder' + '\' + $repo.name + ' ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (:) [Out-File], DirectoryNotFoundException
+ FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand
As stackprotector already commented, the error shows DirectoryNotFoundException, which means you are trying to create a file in a directory that does not yet exist.
To avoid that, first create the path for the output file, then create the file.
$pathOut = Join-Path -Path 'C:\Devjobs\clonefolder' -ChildPath $repo.name
# create the folder path if it does not exist already
$null = New-Item -Path $pathOut -ItemType Directory -Force
# now write the file
$FileContent | Set-Content -Path (Join-Path -Path $pathOut -ChildPath $srccontent.name)
By using the -Force switch on New-Item you will either create the directory, OR have a DirectoryInfo object returned if the folder already existed.
In this case, we have no further need for that object, so we discard it with $null =.
Beware that this only works like that on the file system, if you would do the same on a registry key, you wil lose all content of the existing key!
Note: I use Set-Content rather than Out-File because on PowerShell versions up to and including 5.1, Out-File without using the -Encoding parameter will write the file in Unicode (UTF16-LE) encoding which may or may not be what you expect.
Following your comment:
foreach ($srccontent in $srccontents) {
if (<cond>) {
$slnContent = <rest>
$NewslnContent = "content"
$pathOut = Join-Path -Path 'C:\Devjobs\clonefolder' -ChildPath $repo.name
# first create the folder path if it does not exist already
$null = New-Item -Path $pathOut -ItemType Directory -Force
# now write the file
$NewslnContent | Set-Content -Path (Join-Path -Path $pathOut -ChildPath $srccontent.name)
}
}
Instead of string concatenation you may want to try Join-Path for cross-platform. That being said, if you are on a Windows machine this is not likely to be your issue.
You may want to use Test-Path to verify if the path and the file exists already.
$path = 'C:' |
Join-Path -ChildPath 'Devjobs' |
Join-Path -ChildPath 'clonefolder' |
Join-Path -ChildPath $repo.name
$filepath = $path | Join-Path -ChildPath $srccontent.name
If (-Not (Test-Path $path)) {
New-Item -Type Directory -Path $path
}
If (-Not (Test-Path $filepath)) {
Remove-Item -Path $filepath
}
$FileContent | Out-File $filepath

PowerShell copy-item

I am trying to copy latest 30days files to the folder by this code:
$month = (get-date).AddDays(-30).ToString("yyyMM")
$lastmonthfiles = Write-Host (-join('DCP_', $month,"*.csv"))
Copy-Item -Path Write-Host (-join ("C:\DC+\History\", $lastmonthfiles)) -Destination C:\DC+\History\Backup
but I am having a problem in path in copy-item instruction, which is
Copy-Item : A positional parameter cannot be found that accepts argument 'C:\DC+\History\'.
At line:5 char:1
+ Copy-Item -Path Write-Host (-join ("C:\DC+\History\", $lastmonthfiles ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Copy-Item], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
I am new in PowerShell, and programming so, I could not understand, how can I update and achieve a goal.
Try this:
$Source = Get-Item "C:\Games"
$Destination = "E:\Backup"
$LogFile = "C:\Copy-LogFile.txt"
Copy-Item -Path $( $Source | Where LastWriteTime -LE (Get-Date).AddDays(-30) ) -Destination $Destination -Recurse -PassThru |
Out-File $LogFile -Force
This takes care of your copy function and generates an output log.
Sorry, but your code makes no sense to me...
If it is your aim to copy files to a subfolder in a backup path, try this:
# get the date to use as subfolder to copy to and also to filter the last 30 days files
$refDate = (Get-Date).AddDays(-30).Date # .Date sets it to midnight
# set this variable to the folder where the csv are to be found
$sourceFolder = 'X:\Path\To\Where\The\Files\Are'
# create a destination path to copy to (just a string)
$destination = Join-Path -Path 'C:\DC+\History\Backup' -ChildPath ($refDate.ToString("yyyMM"))
# create this destination folder
$null = New-Item -Path $destination -ItemType Directory -Force
# get the files and copy them to the destination folder
Get-ChildItem -Path $sourceFolder -Filter '*.csv' -File | # filter on CSV fies only
Where-Object { $_.LastWriteTime -ge $refDate } | # filter on date 'last 30 days'
Copy-Item -Destination $destination -Force

Powershell | Rename file with random name

I'm making a script to rename a specific file with a random name. But when running, the following error always occurs:
It is not possible to convert the value ".jpg" to the type "System.Int32". Error: "The input string was not in the correct format."
In C:\Windows\system32\WindowsPowerShell\v1.0\Modules\SetDiscordWallpaper\SetDiscordWallpaper.ps1:7 character:7
+ Rename-Item -Path $file.FullName -NewName ($random + $file.Exte ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastFromStringToInteger
Here is the code I am using
function Set-DiscordWallpaper {
$path = "C:\Windows\Temp\*"
foreach($file in $(Get-ChildItem -Path $path -Include "Wallpaper.jpg")) {
$extension = [System.IO.Path]::GetExtension($file.FullName);
$randomName = [System.IO.Path]::ChangeExtension([System.IO.Path]::GetRandomFileName(), $extension)
$newPath = "C:\inetpub\wwwroot\"
Write-Host "Changing File $($file.Name) to $randomName"
Move-Item -Path $file.FullName -Destination $newPath
}
}
I ask you to help me please. I'm waiting the answer. Thanks
The code (second part in your question) creates the new random filename just fine, only the line Move-Item -Path $file.FullName -Destination $newPath does nothing with that new name and moves the file with its original name to the new path.
Change that line to
Move-Item -Path $file.FullName -Destination (Join-Path -Path $newPath -ChildPath $randomName)
so the file gets moved with the random name in the new path.
Or is your intention to copy the file to its new destination keeping the original filename there and after that rename the original?
In that case do:
Write-Host "Changing File $($file.Name) to $randomName"
Copy-Item -Path $file.FullName -Destination $newPath # copy with original name
$file | Rename-Item -NewName $randomName # rename the original file

Copy Files on Same Directory using Powershell

I am trying to write powershell Script which will create backupfolder on same Path where Application exist and need to copy the folders & files into backupfolder before deploying. Below are the command was using to perform but am getting error
$Source = "C:\XYZ"
$BackupFolder = New-Item -ItemType Directory -Force -Path $source_$(Get-Date)
Copy-Item -Path $Source\* $BackupFolder -Force
Error: Cannot copy item C:\XYZ\Backup_18-02-2017 on to itself
Try:
Copy-Item $Source\* $BackupFolder -Exclude $BackupFolder
That will eliminate the folder that you are copying into as a source that is being copied from.
Variables can contain underscores. The following works and displays the string "asdf"
$a_ = "adsf"; $a_
Your New-Item cmdlet call should have failed since $source_ is not a variable and would return null. This is default behavior for PowerShell. When I run your code as is I get the following:
New-Item : Cannot find drive. A drive with the name '02/18/2017 22' does not exist.At line:1 char:1
+ New-Item -ItemType Directory -Force -Path "$source_$(Get-Date)" -what ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (02/18/2017 22:String) [New-Item], DriveNotFoundException
+ FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.NewItemCommand
So I would have expected your folder variable to be null. wOxxOm brings this up in comment as well
Several options to address what I am sure is the partial source of your issue.
$BackupFolder = New-Item -ItemType Directory -Force -Path "$source`_$(Get-Date)"
$BackupFolder = New-Item -ItemType Directory -Force -Path "$($source)_$(Get-Date)"
$BackupFolder = New-Item -ItemType Directory -Force -Path ("{0}_{1} -f "$source, Get-Date)
You will still have to try and exclude this folder from the copy as well like Keith Hill's answer is telling you
Copy-Item $Source\* $BackupFolder -Exclude $BackupFolder
try Something like this
$Source = "C:\XYZ"
$Destination="{0}{1:yyyyMMdd}" -f $source, (Get-Date)
New-Item -ItemType Directory -Force -Path $Destination
Copy-Item -Path $Source\* $Destination -Recurse -Force
If I understand the question correctly. You want to take "C:\XYZ" and backup into the same directory called "C:\XYZ\backup_$DATE". What you will actually do is create a loop that will break once it reaches the max 248 characters. If we use the -exclude option then we can exclude the backup directory "C:\XYZ\backup_$DATE".
This function will do the trick and also gives you error handling.
Function Get-CopyDirectory{
#####################
# Dynamic Variables #
#####################
$Date = Get-Date -format ddMM-yyyy
$Exclude="Backup*"
####################
# Static Variables #
####################
$AppPath = "F:\Test\"
$BackupPath = "$AppPath\BACKUP_$Date\"
if (Test-Path $BackupPath) {
Write-Host "Backup Exist" -f Cyan
}
else
{
Copy-Item "$AppPath\*" $BackupPath -Exclude $Exclude -recurse -verbose
}
}
CLS
Get-CopyDirectory

Compress-Archive command returns "Exception: Stream was too long."

I have a simple script here to archive logs that begin with the name "Archive" then delete those files leaving only the archive.
cd L:\
$Source = Get-ChildItem L:\ | Where{$_.Name -match "^Archive.*\.evtx$"} |Get-ChildItem -name
$CurrentDate = get-date -Format M.d.yyyy
$Destination = "$CurrentDate.zip"
Compress-Archive -Path $Source -destinationpath $Destination
rm L:\$Source
However, I receive the below error when the script runs:
Exception calling "Write" with "3" argument(s): "Stream was too long." At
C:\windows\system32\windowspowershell\v1.0\Modules\Microsoft.PowerShell.Archive\Microsoft.PowerShell.Archive.psm1:809
char:29
+ ... $destStream.Write($buffer, 0, $numberOfBytesRead)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : IOException
Any suggestions?
Compress-Archive relies upon the Microsoft .NET Framework API System.IO.Compression.ZipArchive to compress files, the maximum file size that you can compress by using Compress-Archive is currently 2 GB. This is a limitation of the underlying API.
Please see more at : here
i would recommend using 7z.exe portable. here is my example script
$TempFolderName = "I:\TempLogs2\"
$source = $TempFolderName+'\Archive'
$destination = $TempFolderName+'\Archive'
$azcopylogs = Get-ChildItem $source -Include *.log -Recurse
foreach ($s in $azcopylogs) {
$azcopylogPath = $s.FullName
$azcopylogName = $s.Name
C:\Tools\7Z\7z.exe a -t7z $azcopylogPath'.7z' -r $azcopylogPath
;if (Test-Path $azcopylogPath'.7z') { Remove-Item $azcopylogPath -force }
}