We help IT Professionals succeed at work.

Powershell script to move old files and create shortcut

bloodywicked
bloodywicked used Ask the Experts™
on
Hello everyone,

Could someone can please help me with creating a PowerShell script that will do the following:

1) Check "\\server1\networkshare" directory (and it's sub-folders) for any files that haven't been modified for 360 days.  AND that are not part of an exculde.txt file (as certain folders and files are required NOT to be archived)

2) If it finds a file(s), then "Move"  to "\\server2\archive\networkshare" and create a shortcut in the original location(s).

Please Note: not sure if this is relevant.  But some of the files that need to archived include "%" and the "&" symbol in their names.  Not really sure how this will be accounted for in the script.

I'm using PowerShell 2.0 CTP 3 and both servers are running win2k3 R2
Thanks in advance
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®

Commented:
Try this!
I suppose, that the "exclude.txt" is in the target folder \\server2\archive\networkshare.
$source = "\\server1\networkshare"
$destination = "\\server2\archive\networkshare"
$days = 360

function test-dir ($d)
{
	if(!(test-path $d)){
		test-dir (split-path $d -parent)
    	[void] (New-Item -Path (split-path $d -parent) -Name (Split-Path $d -Leaf) -ItemType Directory)
	}
}

Get-ChildItem $source -Recurse -Exclude (Get-Content "$target\exclude.txt") | 
	?{!$_.psiscontainer -and $_.lastwritetime -le ((Get-Date).adddays(-($days)))} | %{
			$dest = $_.fullname -replace ($source -replace "\\","\\") , $target
			test-dir (split-path $dest)
			$_ | Move-Item -Destination $dest
		}

Open in new window

Commented:
I suggest for testing purposes, to change the "move-item" in line 17 to "copy-item".

Commented:
Sorry, in line 2 the variablename is $target, not $destination. So the corrected script:
$source = "\\server1\networkshare"
$target = "\\server2\archive\networkshare"
$days = 360

function test-dir ($d)
{
	if(!(test-path $d)){
		test-dir (split-path $d -parent)
    	[void] (New-Item -Path (split-path $d -parent) -Name (Split-Path $d -Leaf) -ItemType Directory)
	}
}

Get-ChildItem $source -Recurse -Exclude (Get-Content "$target\exclude.txt") | 
	?{!$_.psiscontainer -and $_.lastwritetime -le ((Get-Date).adddays(-($days)))} | %{
			$dest = $_.fullname -replace ($source -replace "\\","\\") , $target
			test-dir (split-path $dest)
			$_ | Move-Item -Destination $dest
		}

Open in new window

Author

Commented:
HEllo soostibi,

thanks for your response.  I'm new powershell, so please pardon my dumb questions:

1) what does the [void] actually do, and
2) is split-path the way to create shortcut icons in PS ???

thank you,
Mo

Commented:
1: new-item would give a response after creating the folder, but I do not need that, with the [void] I send this output to nowhere.
2: split-path splits the path to different portions. With the -leaf switch I get the child portion, that is the name of the file or folder I deal with. With the -parent switch I get the path of parent folder of the file or folder.

Commented:
Sorry, I forgot to create the shortcuts. Now this creates them!
$source = "\\server1\networkshare"
$target = "\\server2\archive\networkshare"
$days = 360

function test-dir ($d)
{
	if(!(test-path $d)){
		test-dir (split-path $d -parent)
    	[void] (New-Item -Path (split-path $d -parent) -Name (Split-Path $d -Leaf) -ItemType Directory)
	}
}
$wsh = new-object -comobject wscript.shell

Get-ChildItem $source -Recurse -Exclude (Get-Content "$target\exclude.txt") | 
	?{!$_.psiscontainer -and $_.lastwritetime -le ((Get-Date).adddays(-($days)))} | %{
		$dest = $_.fullname -replace ($source -replace "\\","\\") , $target
		Write-Host ("Linkplace" + "$($_.fullname).lnk") -ForegroundColor Green
		Write-Host ("Linktarget" + $dest) -ForegroundColor Blue
		$shortCut = $wsh.CreateShortCut("$($_.fullname).lnk")	
		$shortCut.TargetPath = $dest
		$shortCut.Description = $_.name
		$shortCut.Save()

		test-dir (split-path $dest)
		$_ | Move-Item -Destination $dest
		}

Open in new window

Author

Commented:
soostibi, thank you soooo much.  Works as expected.  I also tested with deep path and special char in the file names, and it also works fine.  Just one super minor question:

In the exclude file, is there a way to have the script exculde whole directories as well?

i tried the following combos in the exclude file:

..\directory_to_exclude\
fullpath\\directory_to_exclude\
directory_to_exclude\*.*

and none of which seemed to work.  Please advise.  Your help is greatly apperciated.

thank you,
Commented:
I suggest to put the foldername to exclude into a separate text file named "excludedirs.txt" in the target path.
The folder names are not full paths, but any name in the path between slashes.

$source = "\\server1\networkshare"  
$target = "\\server2\archive\networkshare"  
$days = 360  
  
function test-dir ($d)  
{  
        if(!(test-path $d)){  
                test-dir (split-path $d -parent)  
        [void] (New-Item -Path (split-path $d -parent) -Name (Split-Path $d -Leaf) -ItemType Directory)  
        }  
}  
$wsh = new-object -comobject wscript.shell  
$excludedirs = Get-Content "$target\excludedirs.txt"
  
Get-ChildItem $source -Recurse -Exclude (Get-Content "$target\exclude.txt") |   
        ?{!$_.psiscontainer -and $_.lastwritetime -le ((Get-Date).adddays(-($days))) -and $_.extension -ne ".lnk" -and
			($(foreach($dir in $excludedirs) {((split-path $_ -Parent) -split "\\") -notcontains $dir}) -notcontains $false)} | %{  
                $dest = $_.fullname -replace ($source -replace "\\","\\") , $target  
                Write-Host ("Linktarget" + $dest) -ForegroundColor Blue  
                $shortCut = $wsh.CreateShortCut("$($_.fullname).lnk")     
                $shortCut.TargetPath = $dest  
                $shortCut.Description = $_.name  
                $shortCut.Save()  
  
                test-dir (split-path $dest)  
                $_ | Move-Item -Destination $dest  
                }

Open in new window

Author

Commented:
Awsome :) .. I would give a 1000 points if i can .. thank you :)

Author

Commented:
outstanding :)

Author

Commented:
getting this error on several files .. (all with teh same .pif.pif ext.) not sure if that's the case .. any sugguestions?  thank you
 
Exception calling "Save" with "0" argument(s): "Unable to save shortcut "$target\e-tabs\bin\ipwizard.exe.pif.pif.lnk"."
At line:47 char:31
+                 $shortCut.Save <<<< ()  
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : ComMethodTargetInvocation

Commented:
I can not test it, as I could not find any pif files on my computer. But maybe it is not possible to create a shortcut to a pif file, as a pif file is very similar to a shortcut, but it refers to a DOS executable. So maybe that is the problem, Windows does not let you create a LNK file referring to a PIF file.