We need to move .csv files from folder where the are stored down to external server using powershell.
this is what i've tried so far but for some reason i only get message not copying and name of the files:
$DestinationFolder = "C:\d1\"
$SourceFolder = "C:\s1\"
If (-not (Test-Path $DestinationFolder) ) {
New-Item -ItemType Directory -Force -Path $DestinationFolder
}
$EarliestModifiedTime = (Get-Date).AddMinutes(200).Date # get's current time + adds 30 min
$LatestModifiedTime = (Get-Date).Date
echo($DestinationFolder); # will check time
Get-ChildItem "C:\s1\*.*" |
ForEach-Object {
if ( ($_.CreationTime -ge $EarliestModifiedTime) -and ($_.CreationTime -lt $LatestModifiedTime) ){ # i.e., all day yesterday
Copy-Item $_ -Destination $DestinationFolder -Force
Write-Host "Copied $_" }
else {
Write-Host "Not copying $_"
}
}
does it work if you simplify it and just try for a test (e.g. pick one file rather than trying to run for a delta of every 30 mins / last day)? Just thinking first you need to see if the problem is with accessing (or the formatting) of your source / destination directories or the delta logic itself. Perhaps some more error conditions would help....
I want to move some files from one place to another with saving of directory. Result of my script is broken encoding and it doesn't work. I use robocoby, because I have files with names more 256 simbols. I need to move files from different locations. And we are talking about several hundred files.
$source = Get-Content "C:\Users\bill\Downloads\111.TXT" -Encoding UTF8
$destination = "C:\Users\bill\OneDrive\Documents"
foreach($file in $source)
{
robocopy $file $destination /MOVE /E /copyall /log:C:\Users\bill\OneDrive\Documents\log.txt
}
Jane,
Try building your robocopy command like this:
*** UPDATED and TESTED ***
Clear-Host
$source = Get-Content "G:\Test\111.txt" -Encoding UTF8
$destination = "G:\BEKDocs\Test"
Foreach ($SrcPath in $source) {
$file = Split-Path -Path $SrcPath -Leaf
$path = Split-Path -Path $SrcPath -parent
$PLen = $Path.Length -3
$PAdd = $Path.Substring(3,$PLen)
$SavePath = Join-Path -Path $Destination -ChildPath $PAdd
$robocopyOptions = #('/Move', '/copyall')
$LogFile =
#('/log+:G:\BEKDocs\Transfer\log.txt')
$CmdLine = #($path, $SavePath, $file) +
$robocopyOptions + $LogFile
& 'robocopy.exe' $CmdLine
} #End Foreach
Note: Use single quotes as indicated!
Update notes:
Part of the problem was that you had the filenames attached to the paths in your file where RoboCopy wants SourcePath DestPath FileSpec as the first three arguments.
You're copying single files so there is no need for the Recurse /E parameter.
Since you want to preserve the directory structure you need to append the Source path, less the drive (d:) to your destination directory.
You're also calling RoboForm in a loop so you need the /Log+ parameter so each file is appended to the file rather than over writing it.
In my test I copied a file from the base directory, another from one level deep and a third from 2 levels deep. The code preserved the directory structure starting with the specified Destination as the Base or Root directory.
Took a bit of time to figure all this out but I wasn't going to let it go. Hope this works for you!
(I have tried to rewrite this to be more clear)
I have a problem with having hundreds of folders and files (each start with ABC and then numbers 001-936) that need to be moved to a single folder with the same name. For example:
C:\folders\ABC001
C:\folders\random\ABC001\
C:\folders\files\ABC001.pdf
C:\folders\ABC002.pdf
C:\folders\ABC002\
C:\folders\needs sorting\ABC002\
That I would like to move all files and folders to a folder with the same name:
C:\folders\ABC\ABC001\
C:\folders\ABC\ABC002\
and so on...
However, sometimes the orginal folder and/or file will have a duplicate in the destination folder(or may already have since folders already exist), so I want it to add to the name (1), (2), etc.
C:\folders\ABC\ABC001\ABC001\
C:\folders\ABC\ABC001\ABC001 (1)\
C:\folders\ABC\ABC001\ABC001.pdf
C:\folders\ABC\ABC002\ABC002.pdf
C:\folders\ABC\ABC002\ABC002\
C:\folders\ABC\ABC002\ABC002 (1)\
Any help would be greatly appreciated, I have been trying to solve this for weeks (everytime I needed the files) but am new to scripting/code. I started with:
for /R "C:\folders" %x in (*abc123*.*) do move "%x" "D:\folders\abc\abc123"
Closest attempt (minor edits to another code):
function MoveFileToFolder ([string]$source,[string]$destination){
# get a list of source files
$files = Get-ChildItem -Path $source -Recurse | ?{($_.PSIsContainer)}
# verify if the list of source files is empty
if ($files -ne $null) {
foreach ($file in $files) {
$filename = $file.Name
$filebase = $file.BaseName
$fileext = $file.Extension
# verify if destination file exists
$filenameNU = $filename
if (Test-Path (Join-Path $destination $filename)) {
$n = 0
while ((Test-Path (Join-Path $destination $filenameNU)) -eq $true)
{
$filenameNU = $filebase + "(" + ++$n + ")" + $fileext
}
}
Move-Item $file.FullName (Join-Path $destination $filenameNU)
}
}
}
MoveFileToFolder C:\folders\ C:\folders\abc\abc123
(I would try and run this in Powershell for each subfolder, but it became very hard to keep up with)
Thank you for reading.
Trying to improve my PowerShell abilities. Sorry for the noob script.
I am working on a loop that will perform the following against a list of servers:
Removes old folder
Creates new directory
Copy a directory from one host to others on the serverlist
Remove old folderB
Rename the files in the copied directory
I know this is probably inefficient and may be the wrong loop. When ran, the commands all work successfully BUT it does not move on to the other servers in the list. I imagine I am doing something wrong, any ideas?
$strComputers = get-content c:\temp\serverlist3.txt
$source = "\\server\OS\Temp\WSUS\"
$destination = "\\$strComputer\OS\temp\wsus"
$renamea = "\\$strComputer\OS\TEMP\WSUS\clientwsusInstall-win2008-new.cmd"
$renameb = "\\$strComputer\OS\TEMP\WSUS\clientwsusInstall-win2003-new.cmd"
$destinationc = "\\$strComputer\OS\temp\Wsus-new"
# Run through the Array of Computers
##remove old wsus dir
foreach ($strComputer in $strComputers) {
rm -r $destination
new-item -type directory -path $destination
robocopy $source $destination
rm -r $destinationc
rni -path $renamea clientwsusInstall-win2008.cmd
rni -path $renameb clientwsusInstall-win2003.cmd
}
Thanks for you input!!
The problem is simple.
You should assign your variables in the loop, not out of the loop.
Try this:
$strComputers = get-content c:\temp\serverlist3.txt
$source = "\\MGWSUS1\OS\Temp\WSUS\"
# Run through the Array of Computers
##remove old wsus dir
foreach ($strComputer in $strComputers) {
# Only now can the variables be assigned correctly on each iteration.
# ------------------------------------------------------------------
$destination = "\\$strComputer\OS\temp\wsus"
$renamea = "\\$strComputer\OS\TEMP\WSUS\clientwsusInstall-win2008-new.cmd"
$renameb = "\\$strComputer\OS\TEMP\WSUS\clientwsusInstall-win2003-new.cmd"
$destinationc = "\\$strComputer\OS\temp\Wsus-new"
rm -r $destination
new-item -type directory -path $destination
robocopy $source $destination
rm -r $destinationc
rni -path $renamea clientwsusInstall-win2008.cmd
rni -path $renameb clientwsusInstall-win2003.cmd
}
And now slap yourself ;)
I am writing a PowerShell script to create several directories if they do not exist.
The filesystem looks similar to this
D:\
D:\TopDirec\SubDirec\Project1\Revision1\Reports\
D:\TopDirec\SubDirec\Project2\Revision1\
D:\TopDirec\SubDirec\Project3\Revision1\
Each project folder has multiple revisions.
Each revision folder needs a Reports folder.
Some of the "revisions" folders already contain a Reports folder; however, most do not.
I need to write a script that runs daily to create these folders for each directory.
I am able to write the script to create a folder, but creating several folders is problematic.
Try the -Force parameter:
New-Item -ItemType Directory -Force -Path C:\Path\That\May\Or\May\Not\Exist
You can use Test-Path -PathType Container to check first.
See the New-Item MSDN help article for more details.
$path = "C:\temp\NewFolder"
If(!(test-path -PathType container $path))
{
New-Item -ItemType Directory -Path $path
}
Test-Path -PathType container checks to see if the path exists and is a directory. When it does not, it will create a new directory. If the path exists but is a file, New-Item will raise an error (you can overwrite the file by using the -force argument if you are risky).
[System.IO.Directory]::CreateDirectory('full path to directory')
This internally checks for directory existence, and creates one, if there is no directory. Just one line and native .NET method working perfectly.
Use:
$path = "C:\temp\"
If (!(test-path $path))
{
md $path
}
The first line creates a variable named $path and assigns it the string value of "C:\temp"
The second line is an If statement which relies on the Test-Path cmdlet to check if the variable $path does not exist. The not exists is qualified using the ! symbol.
Third line: If the path stored in the string above is not found, the code between the curly brackets will be run.
md is the short version of typing out: New-Item -ItemType Directory -Path $path
Note: I have not tested using the -Force parameter with the below to see if there is undesirable behavior if the path already exists.
New-Item -ItemType Directory -Path $path
The following code snippet helps you to create a complete path.
Function GenerateFolder($path) {
$global:foldPath = $null
foreach($foldername in $path.split("\")) {
$global:foldPath += ($foldername+"\")
if (!(Test-Path $global:foldPath)){
New-Item -ItemType Directory -Path $global:foldPath
# Write-Host "$global:foldPath Folder Created Successfully"
}
}
}
The above function split the path you passed to the function and will check each folder whether it exists or not. If it does not exist it will create the respective folder until the target/final folder created.
To call the function, use below statement:
GenerateFolder "H:\Desktop\Nithesh\SrcFolder"
I had the exact same problem. You can use something like this:
$local = Get-Location;
$final_local = "C:\Processing";
if(!$local.Equals("C:\"))
{
cd "C:\";
if((Test-Path $final_local) -eq 0)
{
mkdir $final_local;
cd $final_local;
liga;
}
## If path already exists
## DB Connect
elseif ((Test-Path $final_local) -eq 1)
{
cd $final_local;
echo $final_local;
liga; (function created by you TODO something)
}
}
When you specify the -Force flag, PowerShell will not complain if the folder already exists.
One-liner:
Get-ChildItem D:\TopDirec\SubDirec\Project* | `
%{ Get-ChildItem $_.FullName -Filter Revision* } | `
%{ New-Item -ItemType Directory -Force -Path (Join-Path $_.FullName "Reports") }
BTW, for scheduling the task please check out this link: Scheduling Background Jobs.
There are three ways I know to create a directory using PowerShell:
Method 1: PS C:\> New-Item -ItemType Directory -path "C:\livingston"
Method 2: PS C:\> [system.io.directory]::CreateDirectory("C:\livingston")
Method 3: PS C:\> md "C:\livingston"
From your situation it sounds like you need to create a "Revision#" folder once a day with a "Reports" folder in there. If that's the case, you just need to know what the next revision number is. Write a function that gets the next revision number, Get-NextRevisionNumber. Or you could do something like this:
foreach($Project in (Get-ChildItem "D:\TopDirec" -Directory)){
# Select all the Revision folders from the project folder.
$Revisions = Get-ChildItem "$($Project.Fullname)\Revision*" -Directory
# The next revision number is just going to be one more than the highest number.
# You need to cast the string in the first pipeline to an int so Sort-Object works.
# If you sort it descending the first number will be the biggest so you select that one.
# Once you have the highest revision number you just add one to it.
$NextRevision = ($Revisions.Name | Foreach-Object {[int]$_.Replace('Revision','')} | Sort-Object -Descending | Select-Object -First 1)+1
# Now in this we kill two birds with one stone.
# It will create the "Reports" folder but it also creates "Revision#" folder too.
New-Item -Path "$($Project.Fullname)\Revision$NextRevision\Reports" -Type Directory
# Move on to the next project folder.
# This untested example loop requires PowerShell version 3.0.
}
PowerShell 3.0 installation.
Here's a simple one that worked for me. It checks whether the path exists, and if it doesn't, it will create not only the root path, but all sub-directories also:
$rptpath = "C:\temp\reports\exchange"
if (!(test-path -path $rptpath)) {new-item -path $rptpath -itemtype directory}
I wanted to be able to easily let users create a default profile for PowerShell to override some settings, and ended up with the following one-liner (multiple statements yes, but can be pasted into PowerShell and executed at once, which was the main goal):
cls; [string]$filePath = $profile; [string]$fileContents = '<our standard settings>'; if(!(Test-Path $filePath)){md -Force ([System.IO.Path]::GetDirectoryName($filePath)) | Out-Null; $fileContents | sc $filePath; Write-Host 'File created!'; } else { Write-Warning 'File already exists!' };
For readability, here's how I would do it in a .ps1 file instead:
cls; # Clear console to better notice the results
[string]$filePath = $profile; # Declared as string, to allow the use of texts without plings and still not fail.
[string]$fileContents = '<our standard settings>'; # Statements can now be written on individual lines, instead of semicolon separated.
if(!(Test-Path $filePath)) {
New-Item -Force ([System.IO.Path]::GetDirectoryName($filePath)) | Out-Null; # Ignore output of creating directory
$fileContents | Set-Content $filePath; # Creates a new file with the input
Write-Host 'File created!';
}
else {
Write-Warning "File already exists! To remove the file, run the command: Remove-Item $filePath";
};
$mWarningColor = 'Red'
<#
.SYNOPSIS
Creates a new directory.
.DESCRIPTION
Creates a new directory. If the directory already exists, the directory will
not be overwritten. Instead a warning message that the directory already
exists will be output.
.OUTPUT
If the directory already exists, the directory will not be overwritten.
Instead a warning message that the directory already exists will be output.
.EXAMPLE
Sal-New-Directory -DirectoryPath '.\output'
#>
function Sal-New-Directory {
param(
[parameter(mandatory=$true)]
[String]
$DirectoryPath
)
$ErrorActionPreference = "Stop"
try {
if (!(Test-Path -Path $DirectoryPath -PathType Container)) {
# Sal-New-Directory is not designed to take multiple
# directories. However, we use foreach to supress the native output
# and substitute with a custom message.
New-Item -Path $DirectoryPath -ItemType Container | `
foreach {'Created ' + $_.FullName}
} else {
Write-Host "$DirectoryPath already exists and" `
"so will not be (re)created." `
-ForegroundColor $mWarningColor
}
} finally {
$ErrorActionPreference = "Continue"
}
}
"Sal" is just an arbitrary prefix for my own library. You could remove it or replace it with your own.
Another example (place here because it otherwise ruins stackoverflow syntax highlighting):
Sal-New-Directory -DirectoryPath ($mCARootDir + "private\")
Example, create a 'Reports' folder inside of the script's folder.
$ReportsDir = $PSScriptRoot + '\Reports'
$CreateReportsDir = [System.IO.Directory]::CreateDirectory($ReportsDir)