Team,
I'm writing a powershell script to automate one of the manual task we are doing daily. I need expert suggestion and help here as I'm new to powershell scripting.
Requirement:
There is a source, destination and a backup folder.
Source may have diff files and files within multiple folders of source.
eg: source\Login.aspx or source\App_Code\BLogic.vb or source\bin\servr.dll etc.
While copying to destination, my source file has to be checked for existence at destination, if exists then we need to copy the current existing file in destination to backup folder, then copy source to destination.
Below are the scripts that i have tried till now.
Script1:
I'm able to list files which are same but not able to copy those array elements to backup location:
#Declare Source and Destination
$source = Get-ChildItem -Recurse -path \\server1\\e$\ps\src\
$dest = Get-ChildItem -Recurse -path \\server2\\e$\ps\dest\
#lists only objects which are equal and assign to variable
$files=compare-Object -DifferenceObject $source -ReferenceObject $dest -IncludeEqual -ExcludeDifferent
$array = #($files)
$len=$array.length
for ($i=0; $i -lt $array.length; $i++)
{
$array[$i]
}
Script2:
As script1 i was facing problem i tried a silly logic with this script, but i feel this is also having too much manual work :( please help me.
Function cpytest ($s, $d)
{
Copy-Item -Path $s -Destination $d;
}
$n = Read-Host "Enter no of files to be uploaded"
$b = Read-Host "Enter Backup Location for file backups"
for ($i=0;$i -lt $n;$i++)
{
$s = Read-Host "Enter Source with complete file name"
$d = Read-Host "Enter Destination with file name too"
$r = Test-Path $d
If ($r -eq "True")
{
cpytest $d $b
cpytest $s $d
}
Else
{
cpytest $s $d
}
}
Try something like this:
Function BackupAndMoveFile($filePath, $backupPath, $deployPath) {
$fileName = Split-Path $filePath -Leaf
$deployFile = Join-Path $deployPath $fileName
if ((Test-Path $deployFile)) {
$backupFile = Join-Path $backupPath $fileName
Move-Item $deployFile $backupFile -Force
if (!(Test-Path $backupFile)) {
Write-Warning "Can't backup $fileName to $backupFile"
return $false
}
}
Copy-Item $filePath $deployPath -Force
if (!(Test-Path $deployPath)) {
Write-Warning "Can't deploy $fileName to $deployPath"
return $false
}
return $true
}
BackupAndMoveFile 'C:\temp\backup-test.txt' `
'C:\temp\backup' `
'C:\temp\deploy'
It will overwrite anything in the backup directory so you might want to modify to add a timestamp.
Related
I want to loop over images and move each into a folder of the creation date, but I seem to fail to see the point about how to format the resulting datetime string and maybe also how ChildItem works...
I intend to create a variable containing the correct formatted string of the creation date "2017-03-06", so that I can create a directory with that name and move the file there. This shall happen within a loop (for, foreach, ...).
$files = Get-ChildItem "P:\photos\"
for ($i=0; $i -lt $files.Count; $i++) {
$outfile = $files[$i].FullName
Write-Host "file: " $outfile
$CreationDateStr = Get-ChildItem $files[$i].CreationTime |
Get-Date -f "yyyy-MM-dd"
Write-Host "file creation time: " $CreationDateStr
}
Read-Host -Prompt "Press Enter to exit"
This does not work, and the code is not correct:
Get-ChildItem : The disc was not found. Not disc with name "03/06/2017 07"
This works, but it needs to be formatted:
$files[$i].CreationTime
file creation time: 06.03.2017 07:53:21
We don't recommend Write-Host because you can't redirect it.
Here's what I think you are looking for:
Get-ChildItem "P:\Photos" | ForEach-Object {
$dirName = "{0:yyyy-MM-dd}" -f $_.CreationTime
if ( -not (Test-Path $dirName -PathType Container) ) {
[Void] (New-Item $dirName -ItemType Directory)
}
Move-Item $_ $dirName -WhatIf
}
So in the loop, we check if the specified directory doesn't exist (create it if it doesn't), then move the file to the new directory. Remove -WhatIf if the code does what you want.
HI Everyone I am trying to write a script for my powershell practice to move a file from one folder to another based on user input. The script works fine but only if the file exists in the folder same as the script. Can someone please help me what i am doing wrong or try to help with logic
$destination = 'P:\Powershell practice\Movefolder'
$ListFile = "P:\Powershell practice\"
get-childitem $ListFile
$Filename = Read-host -prompt "Please Enter File to be moved"
$FileExists = test-path $Filename
If ($FileExists -eq $True) {
move-item $Filename $destination
Write-Host "File is moved to $destination "
}
else
{write-host "No File Found"}
You need to determine the full file path otherwise the test-path check whether the file exists at the current location. You can use the Join-Path cmdlet to join the pass:
$FilePath = Join-Path $ListFile $FileName
$FileExists = test-path $FilePath
If ($FileExists -eq $True) {
move-item $FilePath $destination
...
Offtopic:
You could also use a Grid-View where the user can select multiple files and press the ok button at the bottom to copy the files ;-):
$destination = 'P:\Powershell practice\Movefolder'
$ListFile = 'P:\Powershell practice\'
$filesToMove = get-childitem $ListFile | Out-GridView -OutputMode Multiple
$filesToMove | % { move-item $_.FullName $destination}
Incase if someone needs. Below is the correct working script for this
$destination = 'P:\Powershell practice\Movefolder'
$ListFile = 'P:\Powershell practice\'
get-childitem $ListFile
$Filename = Read-host -prompt "Please Enter File to be moved"
$FilePath = Join-Path $ListFile $FileName
$FileExists = test-path $FilePath
If ($FileExists -eq $True) {
move-item $FilePath $destination
Write-Host "File is moved to $destination "
}
else
{write-host "No File Found"}
I am using powershell to do folder sync. My question is that how does "Copy-Item" use the network bandwidth / speed ? Does it use all available bandwidth? or it is controlled by Windows automatically.
Because my sync process will be performed through vpn, so I would like to control the speed of sync to 500K, is that possible to do it in powershell Like this software does?
function Get-FileMD5 {
Param([string]$file)
$md5 = [System.Security.Cryptography.HashAlgorithm]::Create("MD5")
$IO = New-Object System.IO.FileStream($file, [System.IO.FileMode]::Open)
$StringBuilder = New-Object System.Text.StringBuilder
$md5.ComputeHash($IO) | % { [void] $StringBuilder.Append($_.ToString("x2")) }
$hash = $StringBuilder.ToString()
$IO.Dispose()
return $hash
}
#VARIABLES
$DebugPreference = "continue"
#parameters
$SRC_DIR = 'VPN POINT'
$DST_DIR = 'VPN POINT'
#SCRIPT MAIN
clear
$SourceFiles = GCI -Recurse $SRC_DIR | ? { $_.PSIsContainer -eq $false} #get the files in the source dir.
$SourceFiles | % { # loop through the source dir files
$src = $_.FullName #current source dir file
Write-Debug $src
$dest = $src -replace $SRC_DIR.Replace('\','\\'),$DST_DIR #current destination dir file
if (test-path $dest) { #if file exists in destination folder check MD5 hash
$srcMD5 = Get-FileMD5 -file $src
Write-Debug "Source file hash: $srcMD5"
$destMD5 = Get-FileMD5 -file $dest
Write-Debug "Destination file hash: $destMD5"
if ($srcMD5 -eq $destMD5) { #if the MD5 hashes match then the files are the same
Write-Debug "File hashes match. File already exists in destination folder and will be skipped."
$cpy = $false
}
else { #if the MD5 hashes are different then copy the file and overwrite the older version in the destination dir
$cpy = $true
Write-Debug "File hashes don't match. File will be copied to destination folder."
}
}
else { #if the file doesn't in the destination dir it will be copied.
Write-Debug "File doesn't exist in destination folder and will be copied."
$cpy = $true
}
Write-Debug "Copy is $cpy"
if ($cpy -eq $true) { #copy the file if file version is newer or if it doesn't exist in the destination dir.
Write-Debug "Copying $src to $dest"
if (!(test-path $dest)) {
New-Item -ItemType "File" -Path $dest -Force
}
Copy-Item -Path $src -Destination $dest -Force
}
}
There's a Network Emulator feature in Visual Studio 2010 (and probably newer). Maybe you can get that to work from PowerShell. Otherwise I think you'll have to resort to NetLimiter or one of the alternatives:
TMNetSim
Network Simulator
netem
Robocopy does have the ability though and you can wrap it in PowerShell via Invoke-Expression.
hi i am trying to unzip folders and sub folders i have tried different ways and script but no luck.
Can some one help on this
$Date = Get-Date
#
$folder_date = $Date.ToString("yyyy-MM-dd_HHmmss")
$content = get-childitem 'C:\Deployments'
$sortedContent = $content | Sort-Object LastWriteTime -Descending
# 1. LIST BACKUPS
write-host "This is the list of all the Deployments :"
$count = 1
foreach ($item in $sortedContent)
{
#Edit: Now with auto-incrementing counter
Write-Host ("{0}: {1}" -f $count, $item.Name)
$count++
}
$itemNumber = Read-Host "Please select which deployments you want to copy "
$itemNumber = $itemNumber -1
if($sortedContent[$itemNumber].PSIsContainer -eq $true)
{
$src = $sortedContent[$itemNumber].FullName + "\"
$Date = Get-Date
$folder_date = $Date.ToString("yyyy-MM-dd_HHmm")
$tempPath = 'C:\_Temp\Restore' + $folder_date
if (!(Test-Path -path $tempPath))
{
New-Item $tempPath -type directory
}
$TabletzipPath = $src + "table.zip"
$AdminzipPath = $src + "admin.zip"
.\unzip.ps1 $src $tempPath
.\unzip.ps1 $TabletzipPath $tempPath
.\unzip.ps1 $AdminzipPath $tempPath
}
$Shell = new-object -com shell.application
$Zip = $Shell.NameSpace($PathToZip)
ForEach($Item in $Zip.items())
{
$Shell.Namespace($ExtractPath).copyhere($Item)
}
If your just looking for an easy & quick way of doing this.
You can use this function:
Unzip-File -File C:\location.zip -Destination E:\destination
Need this script:
http://gallery.technet.microsoft.com/scriptcenter/PowerShell-Function-to-727d6200
Using jar unzipping: copy-paste it into PowerShell ISE or create a .ps1 file with this code:
#choose directory where your script is
cd $PSScriptRoot
#do for each file in your directory, -recurse stands for all subfolders, *.jar stands for all files with jar extension
foreach ($file in (dir -Recurse *.jar))
{
#Uncomment this to check files this script is going to unzip (don't forget to comment 7z line below to avoid operation)
#Write-Host ("Dir for file " + $file.Name + " is " + $file.Directory)
#put here full path to 7z if there is no system env (or just make it) for that
#x stands for eXtract files with full paths
#-o is for output folder (example of usage -oc:\test\)
7z x $file.FullName ("-o"+$file.Directory)
}
It should unzip everything you need directly to the folder where your .jar (or any other archive) is.
I need to unzip a specific directory from a zipfile.
Like for example extract the directory 'test\etc\script' from zipfile 'c:\tmp\test.zip' and place it in c:\tmp\output\test\etc\script.
The code below works but has two quirks:
I need to recursively find the directory ('script') in the zip file (function finditem) although I already know the path ('c:\tmp\test.zip\test\etc\script')
With CopyHere I need to determine the targetdirectory, specifically the 'test\etc' part manually
Any better solutions? Thanks.
The code:
function finditem($items, $itemname)
{
foreach($item In $items)
{
if ($item.GetFolder -ne $Null)
{
finditem $item.GetFolder.items() $itemname
}
if ($item.name -Like $itemname)
{
return $item
}
}
}
$source = 'c:\tmp\test.zip'
$target = 'c:\tmp\output'
$shell = new-object -com shell.application
# find script folder e.g. c:\tmp\test.zip\test\etc\script
$item = finditem $shell.NameSpace($source).Items() "script"
# output folder is c:\tmp\output\test\etc
$targetfolder = Join-Path $target ((split-path $item.path -Parent) -replace '^.*zip')
New-Item $targetfolder -ItemType directory -ErrorAction Ignore
# unzip c:\tmp\test.zip\test\etc\script to c:\tmp\output\test\etc
$shell.NameSpace($targetfolder).CopyHere($item)
I don't know about most elegant, but with .Net 4.5 installed you could use the ZipFile class from the System.IO.Compression namespace:
[Reflection.Assembly]::LoadWithPartialName('System.IO.Compression.FileSystem') | Out-Null
$zipfile = 'C:\path\to\your.zip'
$folder = 'folder\inside\zipfile'
$dst = 'C:\output\folder'
[IO.Compression.ZipFile]::OpenRead($zipfile).Entries | ? {
$_.FullName -like "$($folder -replace '\\','/')/*"
} | % {
$file = Join-Path $dst $_.FullName
$parent = Split-Path -Parent $file
if (-not (Test-Path -LiteralPath $parent)) {
New-Item -Path $parent -Type Directory | Out-Null
}
[IO.Compression.ZipFileExtensions]::ExtractToFile($_, $file, $true)
}
The 3rd parameter of ExtractToFile() can be omitted. If present it defines whether existing files will be overwritten or not.
As far as the folder location in a zip is known, the original code can be simplified:
$source = 'c:\tmp\test.zip' # zip file
$target = 'c:\tmp\output' # target root
$folder = 'test\etc\script' # path in the zip
$shell = New-Object -ComObject Shell.Application
# find script folder e.g. c:\tmp\test.zip\test\etc\script
$item = $shell.NameSpace("$source\$folder")
# actual destination directory
$path = Split-Path (Join-Path $target $folder)
if (!(Test-Path $path)) {$null = mkdir $path}
# unzip c:\tmp\test.zip\test\etc\script to c:\tmp\output\test\etc\script
$shell.NameSpace($path).CopyHere($item)
Windows PowerShell 5.0 (included in Windows 10) natively supports extracting ZIP files using Expand-Archive cmdlet:
Expand-Archive -Path Draft.Zip -DestinationPath C:\Reference