I have a script that zips up all files and folders inside a Source folder, and copies them to the Destination folder, then deletes them.
I have added error logging as well.
I am a newbie at Powershell, and although the script works most of the time, some times it does not add the files to the archive, and of course deletes it afterwards so I have no record.
The error logging does not catch this
$Log = "c:\support\scripts\CommsLogArchiveDMLog.txt"
$DestZip="D:\SDM\Fltctrl\MsgBackup\"
$Source = "D:\SDM\Fltctrl\Msglog\ANZ\"
$folder = Get-Item -Path $Source
$ZipTimestamp = Get-Date -format yyyyMMdd-HHmmss;
$ZipFileName = $DestZip + $ZipTimestamp + "_Comms" + ".zip"
$Source
write-output "" >> $Log
write-output $ZipTimestamp >> $Log
Write-output "... Waiting for the zip file to be created" >> $Log
Try
{
set-content $ZipFileName ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
while (!(Test-Path -PathType leaf -Path $ZipFileName))
{
Start-Sleep -s 20
}
}
catch
{
Write-Output "Ran into an issue: $($PSItem.ToString())" >> $Log
}
Try
{
$ZipFile = (new-object -com shell.application).NameSpace($ZipFileName)
}
catch
{
Write-Output "Ran into an issue: $($PSItem.ToString())" >> $Log
}
Write-Output "... Zip file created" >> $Log
Start-Sleep -s 10
write-output "... Adding files to archive" >> $Log
Try
{
$ZipFile.CopyHere($Source)
}
catch
{
Write-Output "Ran into an issue: $($PSItem.ToString())" >> $Log
}
Try
{
$ZipFileName
}
catch
{
Write-Output "Ran into an issue: $($PSItem.ToString())" >> $Log
}
write-output "... Successfully added files to archive" >> $Log
Start-Sleep -s 10
write-output "... Deleting source files" >> $Log
Try
{
Get-ChildItem -Path $Source -Recurse -force |
Where-Object { -not ($_.psiscontainer) } |
Remove-Item –Force
}
catch
{
Write-Output "Ran into an issue: $($PSItem.ToString())" >> $Log
}
write-output "... Successfully deleted source files" >> $Log
Any suggestions o how to get this working as expected would be much appreciated.
Ideally I would like the files to only be deleted if it has been added to the archive successfully.
You should try using the Compress-Archive function. I've never used it before, but it could make your code a little cleaner. Here is what I came up with, but it is untested:
[CmdletBinding(SupportsShouldProcess = $true)]
param (
$Source = "D:\SDM\Fltctrl\Msglog\ANZ\",
$Destination = "D:\SDM\Fltctrl\MsgBackup\",
$Log = "c:\support\scripts\CommsLogArchiveDMLog.txt"
)
function Log ( [String] $Message ) {
Write-Verbose -Message $Message
if ( $Log )
{
"$(Get-Date -Format yyyyMMdd-HHmmss): $Message" | Add-Content $Log
}
}
# Generate .zip filename
$ArchiveFilePath = Join-Path -Path $Destination -ChildPath "$(Get-Date -Format yyyyMMdd-HHmmss)_Comms.zip"
Log -Message "Destination archive filepath: $ArchiveFilePath"
# Compress files
try
{
Compress-Archive -Path $Source -DestinationPath $ArchiveFilePath -CompressionLevel Optimal
}
catch
{
Log -Message "An error occurred creating archive: $($_.ToSTring()) Terminating script."
throw $_
}
# Remove source files
try
{
Get-ChildItem -Path $Source -Recurse -force `
| Where-Object -Property PSIsContainer -EQ -Value $false `
| ForEach-Object `
-Begin { Log -Message "Removing file(s) from $Source"; $Count = 1 } `
-Process {
Log -Message "Removing item: $($_.FullName)"
$_ | Remove-Item -Force
$Count ++
} `
-End { Log -Message "Removed $Count file(s) from $Source" }
}
catch
{
Log -Message "An error occurred removing files: $($_.ToSTring()) Terminating script"
throw $_
}
Related
I'm trying to create a powershell script which checks a log file for lines of text and if the line exists restarts a service and resets/archives the log. I got it working before with 1 "checkstring" if you will, but I've been struggling to get it to work with a list of strings. Could anyone help me figure out where I'm going wrong?
This is the code I'm currently using:
$serviceName = "MySQL80"
$file = "test.txt"
$pwd = "C:\tmp\"
$checkStrings = New-Object System.Collections.ArrayList
# Add amount of checkstrings
$checkStrings.add("Unhandled error. Error message: Error retrieving response.")
$checkStrings.add("Unhandled error. Error message: Error retrieving response. Second")
$logName = "ServiceCheck.log"
$backupFolder = "Archive"
$logString = (Get-Date).ToString("ddMMyyyyHHmmss"), " - The service has been reset and the log moved to backup" -Join ""
Set-Location -Path $pwd
if(Test-Path -Path $file) {
if(Test-Path -Path $backupFolder) {
} else {
New-Item -Path $pwd -Name $backupFolder -ItemType "director"
}
foreach ($element in $checkStrings) {
$containsWord = $fileContent | %{$_ -match $element}
if ($containsWord -contains $true) {
Restart-Service -Name $serviceName
$backupPath = $pwd, "\", $backupFolder, "\", $date, ".log" -join ""
$currentFile = $pwd, "\", $file -join ""
Copy-Item $currentFile -Destination $backupPath
Get-Content $currentFile | select-string -pattern $checkString -notmatch | Out-File $currentFile
if(Test-Path -Path $logName) {
Add-Content $logName $logString
} else {
$logString | Out-File -FilePath $logName
}
}
}
}
I'm using this code to delete files older than 30 days
Function Remove_FilesCreatedBeforeDate {
$Path = "\\servername\path"
$Date = (Get-Date).AddDays(-30)
$ValidPath = Test-Path $Path -IsValid
If ($ValidPath -eq $True) {
"Path is OK and Cleanup is now running"
Get-ChildItem -Path $path -Recurse | Where-Object { $_.LastWriteTime -lt $Date } | Remove-Item -Recurse -force -Verbose
}
Else {
"Path is not a ValidPath"
}
}
Remove_FilesCreatedBeforeDate
Now I want to log which files were deleted, and also whether there was an error or the path isn't valid. Can anyone help me here?
//EDIT
Im Now using this Code (Thanks to Efie for helping)
[Cmdletbinding()]
param(
[Parameter()]$LogPath = 'C:\Admin\scripts\Clean_Folder\Log\log.txt',
[Parameter(ValueFromPipeline)]$Message
)
process {
$timeStampedMessage = "[$(Get-Date -Format 's')] $Message"
$timeStampedMessage | Out-File -FilePath $LogPath -Append
}
}
Function Remove-FilesCreatedBeforeDate {
[Cmdletbinding()]
param(
[Parameter()]$Path = '\\servername\path\',
[Parameter()]$Date = $(Get-Date).AddDays(-30)
)
process {
if(-not (Test-Path $Path -IsValid)) {
"Path $Path was invalid" | Write-MyLog
return
}
"Path $Path is OK and Cleanup is now running" | Write-MyLog
try {
Get-ChildItem -Path $Path -Recurse |
Where-Object {
$_.LastWriteTime -lt $Date
} | Remove-Item -recurse -force -verbose | Write-MyLog
}
catch {
"Remove-Item failed with message $($_.Exception.Message)" | Write-MyLog
}
}
}
Write-MyLog
Remove-FilesCreatedBeforeDate
Two files getting deleted but i just see this in my Log
[2021-07-22T16:27:53] Path \\servername\path\ is OK and Cleanup is now running
I dont see which files getting deleted sadly
A simple implementation for your example would be something like this:
Function Remove-FilesCreatedBeforeDate {
[Cmdletbinding()]
param(
[Parameter(Mandatory)]$Path = '\some\default\path',
[Parameter()]$Date = $(Get-Date).AddDays(-30)
)
process {
if(-not (Test-Path $Path -IsValid)) {
"Path $Path was invalid" | Write-MyLog
return
}
"Path $Path is OK and Cleanup is now running" | Write-MyLog
try {
Get-ChildItem -Path $Path -Recurse |
Where-Object {
$_.LastWriteTime -lt $Date
} | Remove-Item -Recurse -Force -Verbose
}
catch {
"Remove-Item failed with message $($_.Exception.Message)" | Write-MyLog
}
}
}
function Write-MyLog {
[Cmdletbinding()]
param(
[Parameter()]$LogPath = 'default\log\path\log.txt',
[Parameter(ValueFromPipeline)]$Message
)
process {
$timeStampedMessage = "[$(Get-Date -Format 's')] $Message"
$timeStampedMessage | Out-File -FilePath $LogPath -Append
}
}
Some notes:
Advanced Functions
process { }, [Cmdletbinding()], and [Parameter()] are what turn your function into an 'advanced' function. You get to use loads of built in features normally reserved for compiled cmdlets this way.
For example, you could now suppress errors with $ErrorActionPreference = 'SilentlyContinue' like you're used to doing with native Powershell cmdlets.
You can pipe your messages to your logging function by adding ValueFromPipelin to your parameter.
Those really just brush the surface of the extra capabilities you get.
Here is some information. I would recommend getting in the habit of writing them like this if you plan to use them in the future.
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions_advanced?view=powershell-7.1
Error Handling
I'd recommend looking into this documentation by Microsoft on error handling:
https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-exceptions?view=powershell-7.1
Naming Conventions
I would also recommend taking a look at this about PowerShell function naming conventions:
https://learn.microsoft.com/en-us/powershell/scripting/developer/cmdlet/approved-verbs-for-windows-powershell-commands?view=powershell-7
By PowerShell standards it would make more sense to name your function Remove-FilesCreatedBeforeDate with the dash separating verb-action instead of the underscore.
Logging
If you want a little more control and a few more features for logging your functions, here is some information on a tried and true solution for PowerShell using PSFramework:
https://adamtheautomator.com/powershell-logging/
Good luck! Hope some of that helps.
In Unix its Simple
find /var/log/hive -type f -mtime +30 -delete
Could Start-transcript with Try and catch be your solution here?
Start-Transcript logs everything that you do and the errors.
I tried this and this does what you want
Start-Transcript -Path "$PSScriptRoot\RemoveAccountLog.txt" -Force -Append
Get-Date -Format "yyyy-mm-dd HH:MM"
Try
{ # Start Try
$Path = "\\servername\path"
$Date = (Get-Date).AddDays(-30)
$TestPath = Test-Path -Path $Path -PathType Container
If ( $TestPath -Eq $Null )
{ # Start If
Write-Host "The $TestPath String is empty, Path is not a valid"
} # End If
Else
{ # Start Else
Write-host "Path is OK and Cleanup is now running... 0%"
$GetFiles = Get-ChildItem -Path $Path -Recurse -Force |
Where-Object { $_.LastWriteTime -lt $Date } |
Remove-Item -Recurse -force -Verbose |
Write-host "Path is OK and Cleanup is now running... 100%" -ForegroundColor Green
} # End Else
} # End Try
Catch
{ # Start Catch
Write-Warning -Message "## ERROR## "
Write-Warning -Message "## Script could not start ## "
Write-Warning $Error[0]
} # End Catch
Screenshot:
I am using a script I modified slightly to backup user library files. For some reason it can backup all libraries but fails to backup any of the Desktop files.
I've tried running this as various users and on different machines but with the same result.
This is in the latest Powershell version on Windows 10. Perhaps the code has changed since Windows 7? Thanks in advance for any help.
Set-StrictMode -Off
#create directories for backup if needed
$TARGETDIR1 = "c:\temp"
if(!(Test-Path -Path $TARGETDIR1 )){
New-Item -ItemType directory -Path $TARGETDIR1
}
$TARGETDIR2 = "c:\temp\backup"
if(!(Test-Path -Path $TARGETDIR2 )){
New-Item -ItemType directory -Path $TARGETDIR2
}
$TARGETDIR3 = "c:\temp\backup\Download"
if(!(Test-Path -Path $TARGETDIR3 )){
New-Item -ItemType directory -Path $TARGETDIR3
}
$TARGETDIR4 = "c:\temp\backup\Staging"
if(!(Test-Path -Path $TARGETDIR4 )){
New-Item -ItemType directory -Path $TARGETDIR4
}
#Variables, only Change here
$Destination="c:\temp\backup" #Copy the Files to this Location
$Destination="C:\temp\backup\Download"
$Staging="C:\temp\backup\Staging"
$ClearStaging=$true # When $true, Staging Dir will be cleared
$Versions="5" #How many of the last Backups you want to keep
$BackupDirs="$env:USERPROFILE\Desktop", "$env:USERPROFILE\Documents", "$env:USERPROFILE\Downloads", "$env:USERPROFILE\Favorites", "$env:USERPROFILE\Pictures", "$env:USERPROFILE\Videos", "$env:USERPROFILE\OneDrive", "$env:USERPROFILE\Links"#What Folders you want to backup
#commented out for now --tom
$ExcludeDirs="C:\Users\seimi\OneDrive - Seidl Michael\0-Temp\Dir1","C:\Users\seimi\OneDrive - Seidl Michael\0-Temp\Dir2" #This list of Directories will not be copied
$LogName="Log.txt" #Log Name
$LoggingLevel="3" #LoggingLevel only for Output in Powershell Window, 1=smart, 3=Heavy
$Zip=$false #Zip the Backup Destination
$Use7ZIP=$false #Make sure it is installed
$RemoveBackupDestination=$false #Remove copied files after Zip, only if $Zip is true
$UseStaging=$true #only if you use ZIP, than we copy file to Staging, zip it and copy the ZIP to destination, like Staging, and to save NetworkBandwith
#Send Mail Settings
# $SendEmail = $false # = $true if you want to enable send report to e-mail (SMTP send)
# $EmailTo = 'test#domain.com' #user#domain.something (for multiple users use "User01 <user01#example.com>" ,"User02 <user02#example.com>" )
# $EmailFrom = 'from#domain.com' #matthew#domain
# $EmailSMTP = 'smtp.domain.com' #smtp server adress, DNS hostname.
#STOP-no changes from here
#STOP-no changes from here
#Settings - do not change anything from here
$ExcludeString=""
#[string[]]$excludedArray = $ExcludeDirs -split ","
foreach ($Entry in $ExcludeDirs)
{
$Temp="^"+$Entry.Replace("\","\\")
$ExcludeString+=$Temp+"|"
}
$ExcludeString=$ExcludeString.Substring(0,$ExcludeString.Length-1)
#$ExcludeString
[RegEx]$exclude = $ExcludeString
if ($UseStaging -and $Zip)
{
#Logging "INFO" "Use Temp Backup Dir"
$Backupdir=$Staging +"\Backup-"+ (Get-Date -format yyyy-MM-dd)+"-"+(Get-Random -Maximum 100000)+"\"
}
else
{
#Logging "INFO" "Use orig Backup Dir"
$Backupdir=$Destination +"\Backup-"+ (Get-Date -format yyyy-MM-dd)+"-"+(Get-Random -Maximum 100000)+"\"
}
#$BackupdirTemp=$Temp +"\Backup-"+ (Get-Date -format yyyy-MM-dd)+"-"+(Get-Random -Maximum 100000)+"\"
$Log=$Backupdir+$LogName
$Log
$Items=0
$Count=0
$ErrorCount=0
$StartDate=Get-Date #-format dd.MM.yyyy-HH:mm:ss
#FUNCTION
#Logging
Function Logging ($State, $Message) {
$Datum=Get-Date -format dd.MM.yyyy-HH:mm:ss
if (!(Test-Path -Path $Log)) {
New-Item -Path $Log -ItemType File | Out-Null
}
$Text="$Datum - $State"+":"+" $Message"
if ($LoggingLevel -eq "1" -and $Message -notmatch "was copied") {Write-Host $Text}
elseif ($LoggingLevel -eq "3") {Write-Host $Text}
add-Content -Path $Log -Value $Text
}
#Create Backupdir
Function Create-Backupdir {
New-Item -Path $Backupdir -ItemType Directory | Out-Null
sleep -Seconds 5
Logging "INFO" "Create Backupdir $Backupdir"
}
#Delete Backupdir
Function Delete-Backupdir {
$Folder=Get-ChildItem $Destination | where {$_.Attributes -eq "Directory"} | Sort-Object -Property CreationTime -Descending:$false | Select-Object -First 1
Logging "INFO" "Remove Dir: $Folder"
$Folder.FullName | Remove-Item -Recurse -Force
}
#Delete Zip
Function Delete-Zip {
$Zip=Get-ChildItem $Destination | where {$_.Attributes -eq "Archive" -and $_.Extension -eq ".zip"} | Sort-Object -Property CreationTime -Descending:$false | Select-Object -First 1
Logging "INFO" "Remove Zip: $Zip"
$Zip.FullName | Remove-Item -Recurse -Force
}
#Check if Backupdirs and Destination is available
function Check-Dir {
Logging "INFO" "Check if BackupDir and Destination exists"
if (!(Test-Path $BackupDirs)) {
return $false
Logging "Error" "$BackupDirs does not exist"
}
if (!(Test-Path $Destination)) {
return $false
Logging "Error" "$Destination does not exist"
}
}
#Save all the Files
# note - if the folders are empty that are being copied you will see errors
# this shouldn't affect the backup --Tom
Function Make-Backup {
Logging "INFO" "Started the Backup"
$Files=#()
$SumMB=0
$SumItems=0
$SumCount=0
$colItems=0
Logging "INFO" "Count all files and create the Top Level Directories"
}
foreach ($Backup in $BackupDirs) {
$colItems = (Get-ChildItem $Backup -Recurse -File | Where-Object {$_.mode -notmatch "h"} | Measure-Object -property length -sum)
$Items=0
$FilesCount += Get-ChildItem $Backup -Recurse -File | Where-Object {$_.mode -notmatch "h"}
Copy-Item -Path $Backup -Destination $Backupdir -Force -ErrorAction SilentlyContinue
$SumMB+=$colItems.Sum.ToString()
$SumItems+=$colItems.Count
$TotalMB="{0:N2}" -f ($SumMB / 1MB) + " MB of Files"
Logging "INFO" "There are $SumItems Files with $TotalMB to copy"
foreach ($Backup in $BackupDirs) {
$Index=$Backup.LastIndexOf("\")
$SplitBackup=$Backup.substring(0,$Index)
$Files = Get-ChildItem $Backup -Recurse | select * | Where-Object {$_.mode -notmatch "h" -and $_.fullname -notmatch $exclude} | select fullname #$_.mode -notmatch "h" -and
foreach ($File in $Files) {
$restpath = $file.fullname.replace($SplitBackup,"")
try {
Copy-Item $file.fullname $($Backupdir+$restpath) -Force -ErrorAction SilentlyContinue |Out-Null
Logging "INFO" "$file was copied"
}
catch {
$ErrorCount++
Logging "ERROR" "$file returned an error an was not copied"
}
$Items += (Get-item $file.fullname).Length
$status = "Copy file {0} of {1} and copied {3} MB of {4} MB: {2}" -f $count,$SumItems,$file.Name,("{0:N2}" -f ($Items / 1MB)).ToString(),("{0:N2}" -f ($SumMB / 1MB)).ToString()
$Index=[array]::IndexOf($BackupDirs,$Backup)+1
$Text="Copy data Location {0} of {1}" -f $Index ,$BackupDirs.Count
Write-Progress -Activity $Text $status -PercentComplete ($Items / $SumMB*100)
if ($File.Attributes -ne "Directory") {$count++}
}
}
$SumCount+=$Count
$SumTotalMB="{0:N2}" -f ($Items / 1MB) + " MB of Files"
Logging "INFO" "----------------------"
Logging "INFO" "Copied $SumCount files with $SumTotalMB"
Logging "INFO" "$ErrorCount Files could not be copied"
# Send e-mail with reports as attachments
if ($SendEmail -eq $true) {
$EmailSubject = "Backup Email $(get-date -format MM.yyyy)"
$EmailBody = "Backup Script $(get-date -format MM.yyyy) (last Month).`nYours sincerely `Matthew - SYSTEM ADMINISTRATOR"
Logging "INFO" "Sending e-mail to $EmailTo from $EmailFrom (SMTPServer = $EmailSMTP) "
### the attachment is $log
Send-MailMessage -To $EmailTo -From $EmailFrom -Subject $EmailSubject -Body $EmailBody -SmtpServer $EmailSMTP -attachment $Log
}
}
#create Backup Dir
Create-Backupdir
Logging "INFO" "----------------------"
Logging "INFO" "Start the Script"
#Check if Backupdir needs to be cleaned and create Backupdir
$Count=(Get-ChildItem $Destination | where {$_.Attributes -eq "Directory"}).count
Logging "INFO" "Check if there are more than $Versions Directories in the Backupdir"
if ($count -gt $Versions)
{
Delete-Backupdir
}
$CountZip=(Get-ChildItem $Destination | where {$_.Attributes -eq "Archive" -and $_.Extension -eq ".zip"}).count
Logging "INFO" "Check if there are more than $Versions Zip in the Backupdir"
if ($CountZip -gt $Versions) {
Delete-Zip
}
#Check if all Dir are existing and do the Backup
$CheckDir=Check-Dir
if ($CheckDir -eq $false) {
Logging "ERROR" "One of the Directory are not available, Script has stopped"
} else {
Make-Backup
$Enddate=Get-Date #-format dd.MM.yyyy-HH:mm:ss
$span = $EndDate - $StartDate
$Minutes=$span.Minutes
$Seconds=$Span.Seconds
Logging "INFO" "Backupduration $Minutes Minutes and $Seconds Seconds"
Logging "INFO" "----------------------"
Logging "INFO" "----------------------"
if ($Zip)
{
Logging "INFO" "Compress the Backup Destination"
if ($Use7ZIP)
{
Logging "INFO" "Use 7ZIP"
if (-not (test-path "$env:ProgramFiles\7-Zip\7z.exe")) {Logging "WARNING" "7Zip not found"}
set-alias sz "$env:ProgramFiles\7-Zip\7z.exe"
#sz a -t7z "$directory\$zipfile" "$directory\$name"
if ($UseStaging -and $Zip)
{
$Zip=$Staging+("\"+$Backupdir.Replace($Staging,'').Replace('\','')+".zip")
sz a -t7z $Zip $Backupdir
Logging "INFO" "Move Zip to Destination"
Move-Item -Path $Zip -Destination $Destination
if ($ClearStaging)
{
Logging "INFO" "Clear Staging"
Get-ChildItem -Path $Staging -Recurse -Force | remove-item -Confirm:$false -Recurse
}
}
else
{
sz a -t7z ($Destination+("\"+$Backupdir.Replace($Destination,'').Replace('\','')+".zip")) $Backupdir
}
}
else
{
Logging "INFO" "Use Powershell Compress-Archive"
Compress-Archive -Path $Backupdir -DestinationPath ($Destination+("\"+$Backupdir.Replace($Destination,'').Replace('\','')+".zip")) -CompressionLevel Optimal -Force
}
If ($RemoveBackupDestination)
{
Logging "INFO" "Backupduration $Minutes Minutes and $Seconds Seconds"
#Remove-Item -Path $BackupDir -Force -Recurse
get-childitem -Path $BackupDir -recurse -Force | remove-item -Confirm:$false -Recurse
get-item -Path $BackupDir | remove-item -Confirm:$false -Recurse
}
}
}
Write-Host "Press any key to close ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
The output of the log file shows the failure here:
03.05.2019-15:01:04 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\Microsoft Edge.lnk} returned an error an was not copied
03.05.2019-15:01:04 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\Microsoft Teams.lnk} returned an error an was not copied
03.05.2019-15:01:04 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\PRMS Multi-Session.lnk} returned an error an was not copied
03.05.2019-15:01:04 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\PRMS.lnk} returned an error an was not copied
Here is the output Powershell shows
03.05.2019-15:36:07 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\desktop.ini} returned an error an was not copied
03.05.2019-15:36:07 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\REDACTED Logos & Documents.lnk} returned an error an was not copied
03.05.2019-15:36:07 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\REDACTED VPN - Shortcut.lnk} returned an error an was not copied
03.05.2019-15:36:07 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\REDACTED_DigitalNET (J) - Shortcut.lnk} returned an error an was not copied
03.05.2019-15:36:07 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\REDACTED_Sales (S) - Shortcut.lnk} returned an error an was not copied
03.05.2019-15:36:07 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\Slack.lnk} returned an error an was not copied
03.05.2019-15:36:07 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\REDACTED (U) - Shortcut.lnk} returned an error an was not copied
03.05.2019-15:36:07 - ERROR: #{FullName=C:\Users\REDACTED\Desktop\Visual Studio 2019.lnk} returned an error an was not copied
03.05.2019-15:36:07 - INFO: #{FullName=C:\Users\REDACTED\Documents\ConnectWiseControl} was copied
03.05.2019-15:36:07 - INFO: #{FullName=C:\Users\REDACTED\Documents\OneNote Notebooks} was copied
03.05.2019-15:36:07 - INFO: #{FullName=C:\Users\REDACTED\Documents\Visual Studio 2019} was copied
Hello I am new scripting, I am tasked with creating a script that will be deleting a file from specific folders which will be deployed through SCCM onto many computers.
The problem is I want to output the log file saying either:
"<ComputerName> File Terminated"
"<ComputerName> File Not terminated"
Here is what I have so far:
$users = "C:\Users"
$logFile = "C:\TTS\Logs\GoogleTerm.log"
$source = "\AppData\Roaming\Google"
$exclude = "Default"
$input = get-ChildItem -Path $users
foreach ($folder in $input) {
if ($exclude -notcontains $folder.Name) {
Remove-Item -Path ($Users + "\" + $folder.Name + $source) -recurse -force
}
}
echo "Google Terminated on:"$env:computername >> $logfile
Added an else to your if to handle both outcomes, and then using Add-Content instead of echo:
foreach ($folder in $input) {
if ($exclude -notcontains $folder.Name) {
Remove-Item -Path ($Users + "\" + $folder.Name + $source) -recurse -force
Add-Content $logfile "$env:computername File Terminated"
}
else {
Add-Content $logfile "$env:computername File Not Terminated"
}
}
Add-Content $logfile "Google Terminated on: $env:computername"
This was my successfull solution, thank you guys for the assistance!
$users = "C:\Users"
$logFile = "C:\TTS\Logs\GoogleTerm.log"
$exclude = "Default"
$input = get-ChildItem -Path $users
foreach ($folder in $input) {
if ($exclude -notcontains $folder.Name) {
if (Test-Path ($Users + "\" + $folder.Name + $source)){
Remove-Item -Path ($Users + "\" + $folder.Name + $source) -recurse -force
Add-Content $logFile "Google Terminated on: $env:computername UserName:$folder "
}
else{
Add-Content $logFile "Google Already Terminated on:$env:computername UserName:$folder "
}
}
else{
Add-Content $logFile "Not Terminated on: $env:computername Username:$folder"
}
}
I want to move specific files from a local directory to a folder of a remote server.
The files are generated in folders inside the main directory.
The names of the folders are the actual dates and inside them there are files.
In some cases the names of the files are the same but they are in separate folders.
For example:
\main\
\201809271020\a20180927.txt
\201809271120\a20180927.txt
\201809271220\a20180927.txt
I have to move all of the folders and files under the main folder to the remote location.
I've tried it with WinSCP powershell module, but it works on files only. I couldn't move folders with it.
Any helps appreciated.
Regards
wolfnlight
Ok, I create a script, I hope it will not so bad. :)
[xml]$config = Get-Content "C:\Script\config.xml" -ErrorAction Stop
[string]$serverName = $config.Configuration.HostName
[string]$UserName = $config.Configuration.UserName
[string]$localPath = $config.Configuration.LocalPath
[string]$remotePath = $config.Configuration.RemotePath
[string]$logFile = $config.Configuration.LogFile
[string]$SshHostKeyFingerprint = $config.Configuration.SshHostKeyFingerprint
[string]$SshPrivateKeyPath = $config.Configuration.SshPrivateKeyPath
[string]$wildcard = $config.Configuration.WildCard
Import-Module -Name "C:\Program Files (x86)\WindowsPowerShell\Modules\WinSCP" -Force
############# functions for log ##########################################
function InfoToLog {
return "$(get-date -Format "yyyy.MM.dd HH:mm:ss") - [INFO] - "
}
function WarningToLog {
return "$(get-date -Format "yyyy.MM.dd HH:mm:ss") - [WARNING] - "
}
function ErrorToLog {
return "$(get-date -Format "yyyy.MM.dd HH:mm:ss") - [ERROR] - "
}
############ Uploader ####################################################
function Data-Uploader {
param (
$i = 0
)
foreach ($localFile in $localFiles) {
$localDirName = $localFiles[$i].FullName.Substring(38,15)
$localDir = $localPath + $localDirName
$remoteDir = $remotePath + $localDirName
$GetLocalDir = Get-ChildItem -Path $localDir -Recurse -Include "export.end" -ErrorAction Stop
if (($GetLocalDir)) {
# target directory query
if (!(Test-WinSCPPath $session -Path $remoteDir)) {
$(InfoToLog) + $remoteDir + " not exist...creating" | Out-File $logFile -Append
New-WinSCPItem -WinSCPSession $session -Path $remoteDir -ItemType "directory" -Verbose -ErrorAction Stop
$(InfoToLog) + $remoteDir + " created" | Out-File $logFile -Append
}
else {
$(InfoToLog) + $remoteDir + " exists!" | Out-File $logFile -Append
}
$localFileName = $localFiles[$i].FullName
$remotefileName = $localFiles[$i].Name
# put files from local directory to remote directory - same name
if ($localFileName -like "*$localDir*") {
$localFile = "FileName: " + $localFile.Name + " - CreationTime: " + $localFile.CreationTime.GetDateTimeFormats('u') + "- Length(kB): " + $localFile.Length
$(InfoToLog) + $localFile | Out-File $logFile -Append
$(InfoToLog) + "Transfering $remotefileName ..." | Out-File $logFile -Append
Send-WinSCPItem -TransferOptions $TransferOptions `
-WinSCPSession $session `
-LocalPath "$localDir\$wildcard" `
-RemotePath $remoteDir -ErrorAction Stop -Verbose
$(InfoToLog) + "$remotefileName transfered." | Out-File $logFile -Append
$(InfoToLog) + "Archiving files..." | Out-File $logFile -Append
Move-Item -Path $localDir -Destination "C:\Script\Archive\" -Force -ErrorAction Stop -Verbose
$(InfoToLog) + "Archiving completed." | Out-File $logFile -Append
}
else {
$(InfoToLog) + "No file for transfer." | Out-File $logFile -Append
}
}
else {
$(WarningToLog) + "$localFile - waiting for export ended!" | Out-File $logFile -Append
}
$i++
}
}
################# process ######################################
try {
$(InfoToLog) + "Data_Uploader - version 1.2 - Starting script..." | Out-File $logFile -Append
# set user
$MyCredential = New-Object System.Management.Automation.PSCredential ($UserName, (new-object System.Security.SecureString))
# set session
$sessionOption = New-WinSCPSessionOption -Credential $MyCredential -HostName $serverName -Protocol sftp -SshHostKeyFingerprint $SshHostKeyFingerprint -SshPrivateKeyPath $SshPrivateKeyPath
$TransferOptions = New-WinSCPTransferOption -FileMask $wildcard -TransferMode Binary
# connecting
$session = New-WinSCPSession -SessionOption $sessionOption -ErrorAction Stop -SessionLogPath "C:\Script\MUK\Log\Muk_Uploader_session.log"
# session available
if ($session.Opened -eq $true) {
$(InfoToLog) + "Connected to $servername..." | Out-File $logFile -Append
# get local files
$localFiles = Get-ChildItem -Path $localPath -Recurse -ErrorAction Stop -Verbose -Attributes !Directory -Exclude "riport.end"
# existing files in local dir
if ($localFiles.Count -gt 0) {
$(InfoToLog) + $localFiles.Count +" files in $localPath :" | Out-File $logFile -Append
# upload files
Data-Uploader
}
else {
$(InfoToLog) + "No files in $localPath" | Out-File $logFile -Append
}
}
else {
$(ErrorToLog) + "$($_.Exception.Message)" | Out-File $logFile -Append
}
} # try
catch {
Write-Host -ForegroundColor Green "Error: $($_.Exception.Message)"
$(ErrorToLog) + "Message: $($_.Exception.Message)" | Out-File $logFile -Append
# session close
Remove-WinSCPSession -WinSCPSession $session -ErrorAction Stop
}
finally {
$(InfoToLog) + "End script!" | Out-File $logFile -Append
"$(get-date -Format "yyyy.MM.dd HH:mm:ss") - ***************************************************************************************************" | Out-File $logFile -Append
# session close
Remove-WinSCPSession -WinSCPSession $session -ErrorAction Stop
}
Any suggestions?