[Powershell & Robocopy] Backup Script wait event?

Pagina: 1
Acties:

Onderwerpen


  • MuVo
  • Registratie: Februari 2008
  • Laatst online: 07:09
Ik heb reeks een backup script gemaakt met Powershell en Robocopy. Dit script maakt een kopie van x bestanden/mappen. Plaatste ze naar nader op te geven bestemming (bijv netwerk locatie). Archiveerd de eerder gemaakte backup met 7 Zip, en bewaard deze maximaal 5 keer. de 6de wordt verwijderd. Het resultaat(gelukt of mislukt) en de log wordt gemaild naar de admin.

Nu is het probleem dat dit script prima lokaal werkt, maar via het netwerk speeld latecy mee (tussen Belgie en Amerika). Hierdoor is Robocopy nog niet klaar met700 mb kopieren terwijl het script de output al probeerd te zippen en de log probeerd te mailen.

Het gaat om dit script:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#*=============================================
#* Base variables
#*=============================================
$SourceFolder = "\\**\****\*****\Data"
$DestinationFolder = "\\\\**\****\*****\Program"
$DestinationFoldername = "Data"
$Logfile_archive_location = "\\\\**\****\*****\Archive\"
$maxcopies = "5"                                                    #* maximum age in days of  a file when it should be removed.

#*=============================================
#* Email variables
#*=============================================

$Subject = "Robocopy Results: Backup Data - From server *** to Networkshare //****"
$Sender = "Server *****<***@****.com>"
$Recipients = "User1 <***@***.com>"
$Admin = "Admin <***@**.com>"


#*=================================================== Do not change settings below ===================================================================

#*=============================================
#* Variables
#*=============================================
$TIMESTAMP = get-date -format "dd-MM-yy H-m"                          #* Current PC time, format day, month year.
$pathTo7ZipExe = "C:\Program Files (x86)\7-zip\7z.exe"                #* Path of 7-zip


#*=============================================
#* Email Server
#*=============================================
$SMTPServer = "mail"
$SendEmail = $True
$IncludeAdmin = $True
$AsAttachment = $True


#*=============================================
#* RoboCopy
# Change robocopy options as needed. ( http://ss64.com/nt/robocopy.html )
#*=============================================

$Log_filename = "Backup history " + $TIMESTAMP + ".log"


robocopy $SourceFolder $DestinationFolder\$DestinationFoldername /MIR /E /LOG:$Logfile_archive_location\$Log_filename /w:1 /r:10 /tee


#*=============================================
#* Create the backup files as one zip fole with 7zip
#*=============================================

function create-7zip([String] $aDirectory, [String] $aZipfile){
        [Array]$arguments = "a", "-tzip", "$aZipfile", "$aDirectory", "-r";
    & $pathTo7ZipExe $arguments;
}

create-7zip $DestinationFolder\$DestinationFoldername "$Logfile_archive_location\Archive\Backup of $TIMESTAMP.zip"


#*=============================================
#* Keeps latest 5 files from a directory based on Creation Time
#*============================================= 

#Declaration variables
$path = "$Logfile_archive_location\Archive\"                            
$total= (ls $path).count - $maxcopies # Change number 5 to whatever number of objects you want to keep

ls $path |sort-object -Property {$_.CreationTime} | Select-Object -first $total | Remove-Item -force


#*=============================================
#* E-Mail SCRIPT 
#*=============================================
# The following attempts to get the error code for Robocopy
# and use this as extra infromation and email determination.
# NO OTHER CODE BETWEEN THE SWITCH AND THE ROBOCOPY COMMAND
Switch ($LASTEXITCODE)
{
16
{
$exit_code = "16"
$exit_reason = "***FATAL ERROR***"
#$IncludeAdmin = $True
#$SendEmail = $True
}
8
{
$exit_code = "8"
$exit_reason = "**FAILED COPIES**"
#$IncludeAdmin = $$True
#$SendEmail = $True
}
4
{
$exit_code = "4"
$exit_reason = "*MISMATCHES*"
$IncludeAdmin = $True
#$SendEmail = $True
}
2
{
$exit_code = "2"
$exit_reason = "EXTRA FILES"
$IncludeAdmin = $False
#$SendEmail = $False
}
1
{
$exit_code = "1"
$exit_reason = "Copy Successful"
$IncludeAdmin = $False
#$SendEmail = $False
}
0
{
$exit_code = "0"
$exit_reason = "No Change"
$SendEmail = $False
$IncludeAdmin = $False
}
default
{
$exit_code = "Unknown ($LASTEXITCODE)"
$exit_reason = "Unknown Reason"
#$SendEmail = $False
$IncludeAdmin = $False
}
}

# Modify the subject with Exit Reason and Exit Code
$Subject += " : " + $exit_reason + " EC: " + $exit_code

# Test log file size to determine if it should be emailed
# or just a status email
If ((Get-ChildItem $Logfile).Length -lt 25mb)
{
If ($IncludeAdmin)
{
If ($AsAttachment)
{
Send-MailMessage -From $Sender -To $Recipients -Cc $Admin -Subject $Subject -Body "Robocopy results are attached." -Attachment $Logfile_archive_location"$Log_filename" -DeliveryNotificationOption onFailure -SmtpServer $SMTPServer
} Else {
Send-MailMessage -From $Sender -To $Recipients -Cc $Admin -Subject $Subject -Body (Get-Content $LogFile | Out-String) -DeliveryNotificationOption onFailure -SmtpServer $SMTPServer
}
} Else {
If ($AsAttachment)
{
Send-MailMessage -From $Sender -To $Recipients -Subject $Subject -Body "Robocopy results are attached." -Attachment $Logfile_archive_location"$Log_filename" -DeliveryNotificationOption onFailure -SmtpServer $SMTPServer
} Else {
Send-MailMessage -From $Sender -To $Recipients -Subject $Subject -Body (Get-Content $LogFile | Out-String) -DeliveryNotificationOption onFailure -SmtpServer $SMTPServer
}
}
} Else {
# Creat the email body from the beginning and end of the $Logfile
$Body = "Logfile was too large to send." + (Get-Content $LogFile -TotalCount 15 | Out-String) + (Get-Content $Logfile_archive_location"$Log_filename" | Select-Object -Last 13 | Out-String)
# Include Admin if log file was too large to email
Send-MailMessage -From $Sender -To $Recipients -Cc $Admin -Subject $Subject -Body $Body -DeliveryNotificationOption onFailure -SmtpServer $SMTPServer
#Exclude Admin if log file was too large to email
#Send-MailMessage -From $Sender -To $Recipients -Subject $Subject -Body $Body -DeliveryNotificationOption onFailure -SmtpServer $SMTPServer
}

#*=============================================
#* END OF SCRIPT
#*=============================================


In het mailscript zit nog een kleine status update bug

Nu heb ik geprobeerd een wait event in te bouwen die wacht met het script uit te voeren tot RoboCopy voltooid is. Doormiddel van:

code:
1
2
3
4
$Prog = "C:\Windows\SysWOW64\cmd.exe"
$arg = "robocopy $SourceFolder $DestinationFolder\$DestinationFoldername /MIR /E /LOG:$Logfile_archive_location\$Log_filename /w:1 /r:10 /tee
"
Start-Process $Prog $arg -Wait


of
code:
1
2
3
4
$Prog = "robocopy"
$arg = "$SourceFolder $DestinationFolder\$DestinationFoldername /MIR /E /LOG:$Logfile_archive_location\$Log_filename /w:1 /r:10 /tee
"
Start-Process $Prog $arg -Wait


Maar dit werkt niet, hierdoor wordt cmd wel gestart en gesloten maar het robocypy script niet uitgevoerd en gaat door naar 7zip.

Verder heb ik nog andere foefjes geprobeerd. Bijvoorbeeld door het script te verdelen in verschilelnde Ps1 bestanden en die na elkaar proberen uit te voeren (net zoals het command promtCall geprobeerd. Maar dan krijg ik niet alle parameters mee. Bijvoorbeeld Date.

Heeft er iemand nog een idee hoe ik een correct wait event inbouw?


Andere info die ik nog niet toegepast krijg:
http://dmcodeworks.wordpress.com/tag/robocopy/

Zelf ben ik niet echt een programeur, dus ik was al blij dat ik dit lokaal werkend heb gekregen. :)

Acties:
  • 0 Henk 'm!

  • Cloud
  • Registratie: November 2001
  • Laatst online: 10:39

Cloud

FP ProMod

Ex-moderatie mobster

Het zal absoluut en gegarandeerd mooier kunnen maar wat ik zelf in een dergelijke situatie deed was gewoon een leeg bestand klaarzetten op het moment dat het eerste proces klaar was. Het tweede proces begon pas met uitvoer totdat het betreffende bestand bestond (heh).

Maar nogmaals, het kan vast netter :P Ben zelf ook wel geïnteresseerd in een mooie oplossing hiervoor.

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


Acties:
  • 0 Henk 'm!

  • Craven
  • Registratie: Februari 2007
  • Laatst online: 10:14
Cloud schreef op vrijdag 21 februari 2014 @ 13:48:
Het zal absoluut en gegarandeerd mooier kunnen maar wat ik zelf in een dergelijke situatie deed was gewoon een leeg bestand klaarzetten op het moment dat het eerste proces klaar was. Het tweede proces begon pas met uitvoer totdat het betreffende bestand bestond (heh).

Maar nogmaals, het kan vast netter :P Ben zelf ook wel geïnteresseerd in een mooie oplossing hiervoor.
Ietsjes netter is alvast het bestand vervangen door een variabele.
code:
1
2
3
*actie1
$Actie1 = "finished"
if ($Actie1 -eq "finished"){ *Actie2}

Acties:
  • 0 Henk 'm!

  • Cloud
  • Registratie: November 2001
  • Laatst online: 10:39

Cloud

FP ProMod

Ex-moderatie mobster

Dat kan natuurlijk ook :) Ik ging er (misschien onterecht) vanuit dat het twee verschillende scripts zijn die onafhankelijk van elkaar gestart worden.

Never attribute to malice that which can be adequately explained by stupidity. - Robert J. Hanlon
60% of the time, it works all the time. - Brian Fantana


Acties:
  • 0 Henk 'm!

  • xAn52
  • Registratie: Maart 2001
  • Laatst online: 06-05 22:07

xAn52

Whatever...

http://stackoverflow.com/...ile-external-program-runs
Idee?
code:
1
2
3
4
5
6
7
8
& program1.exe 
while ($true) {
    Start-Sleep -Seconds 1
    if (-not (Get-Process -Name program1 -ErrorAction SilentlyContinue)) {
        break
    }
}
"...continue here"

Acties:
  • 0 Henk 'm!

  • Squ1zZy
  • Registratie: April 2011
  • Niet online
Waarom niet geheel in PS? En de opmaak komt door het pasten? Het is moeilijk lezen zo zonder nette opmaak. Je zou het in PS kunnen maken zodat de volgende regel pas wordt uitgevoerd. Wat je ook kunt doen is een check. Kijken hoeveel data er op A staat en die vergelijken op B.

Ik heb meerdere van deze scripts gemaakt waarbij ik ook een MD5 check deed of het bestand goed gekopieerd is.

De laatste exit codes heb je dan niet nodig. Ook zou het mooi zijn als je een mail functie zou maken met arguments. Zo kan je het mail gedeelte altijd makkelijk in andere scripts gebruiken.

Tip: Gebruik geen sleeps etc. Dat is wel een voorbeeld van slecht programmeren ;)

Edit: Zal ik eens wat maken en dit posten? Weet niet of je daar interesse in hebt (testen, implementeren etc.). Stuur me dan een DM :)

[ Voor 8% gewijzigd door Squ1zZy op 21-02-2014 21:53 ]


Acties:
  • 0 Henk 'm!

  • Frost_Azimov
  • Registratie: Juni 2004
  • Laatst online: 11-09 21:36
De methode diexAn52 aandraagt vind ik leuk gevonden, en eigelijk best netjes. Ik vermoed dat het wel werkt. Maar het lijkt me dat je er met je eigen code ook al bijna bent: je gebruikt immers Start-process, en die kan wachten op het process. (en exit codes terug geven!)


Probeer eens zoiets:

$SourceFolder = "\\server\folder\blabla"
$destfolder = "c:\temp\bla"
$log = "c:\temp\roblog.log"

$arg = "$SourceFolder $destfolder /MIR /E /LOG:$log /w:1 /r:10 /tee"
$proc = Start-Process "Robocopy" $arg -Wait -NoNewWindow -PassThru
$proc.HasExited
$proc.ExitCode

Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 16-09 22:28

Matis

Rubber Rocket

Ik heb zelf ook wel eens problemen gehad met het schrijven naar/lezen van netwerkmounts die beginnen met \\. Ik mount nu vaak een webdrive met een drive-letter gedurende het script en daarna unmount ik hem weer.
Het staat helemaal lost van jouw probleem, maar houd het in je achterhoofd mocht je tegen problemen aanlopen.

If money talks then I'm a mime
If time is money then I'm out of time


Acties:
  • 0 Henk 'm!

  • MuVo
  • Registratie: Februari 2008
  • Laatst online: 07:09
Bedankt voor de informatie! Dit projectje is voor mij een tijdje stil gaan liggen, vanwege andere proiteiten.

Momenteel heb ik het voor elkaar gekregen om net stap voor stap laten uitvoeren, wonderbaarlijk zonder wat extra code toe te voegen.

Zie onderstaande stukje van de code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#*=============================================
#* RoboCopy
# Change robocopy options as needed. ( http://ss64.com/nt/robocopy.html )
#*=============================================

$Log_filename = "Backup history " + $TIMESTAMP + ".log"

mkdir -p $DestinationFolder -Force
mkdir -p $Archive_location -Force
mkdir -p $Logfile_location -Force        




Robocopy "$SourceFolder" "$DestinationFolder$DestinationFoldername" /MIR /E /LOG:"$Logfile_location\$Log_filename" /w:1 /r:10 /tee 

#*=============================================
#* Store the error ID of Robocopy
#*============================================= 
Switch ($LASTEXITCODE)
{

****
}

#*=============================================
#* Create the backup files as one zip fole with 7zip
#*=============================================


function create-7zip([String] $aDirectory, [String] $aZipfile){
        [Array]$arguments = "a", "-tzip", "$aZipfile", "$aDirectory", "-r", "/LOW";
    & $pathTo7ZipExe $arguments;
}

create-7zip "$DestinationFolder\$DestinationFoldername"  "$Archive_location\Backup of $TIMESTAMP.zip" = Get-Process



Heb het script een aantal weken laten proef draaien en het werkt naar behoren. Wat iet script doet is het volgende: Maakt een kopie met robocopy. Na het kopiëren pakt het bestand de gekopieerde bestanden in.

Het script kan met een event wekelijks worden uitgevoerd, na de eerste kopie wordt de bestemmingsfolder bijgewerkt, niet overschreven of verwijderd (scheelt bandbreedte). Het script maakt maximaal 3 zip kopies. de 6de (oudste) wordt verwijderd. Na elke kopieer actie wordt er een mail gestuurd met de melding of het gelukt is of niet (als er een fout is staat de fout code er bij).
Pagina: 1