[Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

How to us a powershell script to copy

Posted on 2010-01-05
19
Medium Priority
?
846 Views
Last Modified: 2013-11-10
I am still a novice when it comes to scripting & am trying to learn as I go.
I'm not certain if powershell will do what I want it to, but I am hoping someone with more know-how could provide me with the PS code to do the following.

I wish the script to create a directory, at the end of a path, with a unique name, say... today's date.
Copy files of multiple types from one directory into this JUST MADE directory, such as all *.xls & *.doc type files.

An additional problem I seem to be running up against is that PS is in restricted mode, which I know that this is not something you'd simply want to disable, but I don't quite yet understand how to sign a script so that it'll run.

Also, can PS scripts be run via a scheduled task?
0
Comment
Question by:alexianit
  • 10
  • 9
19 Comments
 
LVL 71

Expert Comment

by:Chris Dent
ID: 26180314

You'd need a code-signing certificate, I could never justify the cost. Unless you're troubled by it I advise changing the ExecutionPolicy to RemoteSigned, with:

Set-ExecutionPolicy RemoteSigned

That means that remotely executed scripts will require signing, locally executed will be fine.

And yes, they can be run as scheduled tasks. For example, feed the scheduled task a command like this:

PowerShell.exe Script1.ps1

You can also execute PowerShell Commands directly, or pass in arguments, it all depends on what you need.

Chris
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 26180381

And then this bit :)

> I wish the script to create a directory, at the end of a path, with a unique name, say... today's date.
> Copy files of multiple types from one directory into this JUST MADE directory, such as all *.xls & *.doc type files.

Okay... no problem. How would you like the Directory to appear?

Perhaps for the directory:

$Directory = mkdir "SomeDirectory-$((Get-Date).ToString('dd.MM.yyyy'))"

mkdir is an alias for "New-Item <Path> -Type Directory" rather than it being the DOS command.

Then for the copy part...

Copy-Item *.xls, *.doc $Directory.FullName

Are the files spread around a number of source folders?

Chris
0
 

Author Comment

by:alexianit
ID: 26180541
Here's an example of what I want:

All files reside in a single directory
Source: \\ServernameA\Program Files\Dir01\subdir\*.txt
copy to: \\ServernameB\Public\Dir02\timestamp\*.txt

or maybe:
Source: C:\Program Files\Dir01\subdir\*.txt
copy to: \\ServernameB\Public\Dir02\timestamp\*.txt

& would the target machine need PS installed?  Its an embedded NAS box, although the destination could be altered to a different box.
0
Get your Conversational Ransomware Defense e‑book

This e-book gives you an insight into the ransomware threat and reviews the fundamentals of top-notch ransomware preparedness and recovery. To help you protect yourself and your organization. The initial infection may be inevitable, so the best protection is to be fully prepared.

 

Author Comment

by:alexianit
ID: 26180545
the directory name should really only be the date
0
 

Author Comment

by:alexianit
ID: 26180681
Taking a closer look at this sourcedirectory of mine I am noticing there is quite a diverse range of file types, including some with no extension.  Its a programs data directory that we are attempting a simple, copy backup of.

Would it be better to simply use  *.*  rather than *.doc etc... ?  & will that get the files without an extension?
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 26180722

> would the target machine need PS installed?  

No. Only the system running the script.

We need to identify the steps for this. First one is to create the date-stamped directory.

$Directory = New-Item -Name $((Get-Date).ToString('dd.MM.yyyy')) -Type Directory -Path "\\ServernameB\Public\Dir02\"

We can change how the time stamp is formatted, I made that one up, it's not a fixed name.

Once we have the directory we need a way to identify which files are interesting. In the example above, I'd done that with Copy-Item's acceptance of wild-cards. We can use Get-ChildItem to introduce greater flexibility if that doesn't give enough.

Finally, having identified the files they need copying to the newly created directly. The step was combined with the previous for simplicity. So you could do:

$SourceDir = "\\ServernameA\Program Files\Dir01\subdir\"
Copy-Item "$SourceDir\*.txt", "$SourceDir\*.doc" -Destination $Directory.FullName

As long as you can split a process up into small steps you can script it.

Chris
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 26180734

> Would it be better to simply use  *.*  rather than *.doc etc... ?  & will that get the files without an extension?

Using *.* will show all files that contain a dot. You'd be better leaving it at * to capture everything.

Are you wanting to capture files created / modified on a particular day for the copy? Or just everything?

Chris
0
 

Author Comment

by:alexianit
ID: 26180946
leave it to me to complicate things  ...
Only the files within the directory, not the subfolders or their chiildren
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 26180971

We might be better with Where-Object then, greater flexibility. Give this a try?

$SourceDir = "\\ServernameA\Program Files\Dir01\subdir\"
Get-ChildItem "$SourceDir\*" | `
  Where-Object{ $_.PsIsContainer -eq $False } | `
  Copy-Item $_.FullName -Destination $Directory.FullName

Chris
0
 

Author Comment

by:alexianit
ID: 26181282
Ok, to verify ... this is basically what I have so far.
I've modified the paths to reflect a little closer to what I have.  I haven't tested yet, but this should yield the desired results?


$Directory = New-Item -Name $((Get-Date).ToString('dd.MM.yyyy')) -Type Directory -Path "\\NASBOX\Public\program data backup\"

$SourceDir = "\\Server\Program Files\Appname\Programs\data\"
Get-ChildItem "$SourceDir\*" | `
  Where-Object{ $_.PsIsContainer -eq $False } | `
  Copy-Item $_.FullName -Destination $Directory.FullName

Open in new window

0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 26181305

We need to lose the final "\" from SourceDir, or drop the \ we add in Get-ChildItem (I've done that below).

PowerShell has a -WhatIf parameter that allows a bit of a different level of testing. Lets have that in while testing (we only need it for the Copy-Item command).

Chris
$Directory = New-Item -Name $((Get-Date).ToString('dd.MM.yyyy')) -Type Directory -Path "\\NASBOX\Public\program data backup\"

$SourceDir = "\\Server\Program Files\Appname\Programs\data\"
Get-ChildItem "$SourceDir*" | `
  Where-Object{ $_.PsIsContainer -eq $False } | `
  Copy-Item $_.FullName -Destination $Directory.FullName -WhatIf

Open in new window

0
 

Author Comment

by:alexianit
ID: 26182325
I get the following error:

Copy-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\test.ps1:6 char:12
+   Copy-Item <<<<  $_.FullName -Destination $Directory.FullName -WhatIf
    + CategoryInfo          : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand
0
 

Author Comment

by:alexianit
ID: 26182337
however the directory is being created as desired
0
 
LVL 71

Accepted Solution

by:
Chris Dent earned 2000 total points
ID: 26183008

Apologies, a bit too rushed writing that it seems.

Try this version?

Chris
$Directory = New-Item -Name $((Get-Date).ToString('dd.MM.yyyy')) -Type Directory -Path "\\NASBOX\Public\program data backup\"

$SourceDir = "\\Server\Program Files\Appname\Programs\data\"
Get-ChildItem "$SourceDir*" | `
  Where-Object { $_.PsIsContainer -eq $False } | ForEach-Object {`
  Copy-Item $_.FullName -Destination $Directory.FullName -WhatIf }

Open in new window

0
 

Author Comment

by:alexianit
ID: 26184002
OK looks good.
I ran this in Powershell_ISE.exe and from what I can tell the test results look excellent.

now I need to remove the -whatif parmater, do I just delete '-whatif' ?
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 26184011

Yep, that's right :)

Chris
0
 

Author Closing Comment

by:alexianit
ID: 31672908
Thank you very much ... most excellent!
0
 

Author Comment

by:alexianit
ID: 26184123
One last bit.  The script is great.  You mentioned earlier to feed the scheduled task something like this:

PowerShell.exe Script1.ps1

should it rather be:
C:\WINDOWS\system32\WINDOW~2\v1.0\POWERS~1.EXE C:\Script1.ps1

Its just that when I set up the task it asks what program to run, perhaps I should only reference the script and not the Powershell.exe?
0
 
LVL 71

Expert Comment

by:Chris Dent
ID: 26184163

PowerShell.exe is (or should be) in the system path so shouldn't need all of that :)

You can't actually execute PowerShell scripts without telling it to use PowerShell.exe first (either by double-clicking or just using the script name), a design choice by MS at the outset, I guess they didn't want to encourage abuse of yet another windows scripting language.

Chris
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you are a mobile app developer and especially develop hybrid mobile apps then these 4 mistakes you must avoid for hybrid app development to be the more genuine app developer.
The Internet has made sending and receiving information online a breeze. But there is also the threat of unauthorized viewing, data tampering, and phoney messages. Surprisingly, a lot of business owners do not fully understand how to use security t…
Simple Linear Regression
Progress

868 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question