none
Power-shell Script for sending notification after completion of coping of multiple files in recurring folders with clean up and logs. RRS feed

  • Question

  • Hi All,

    I have created the power shell script for above question but one logic is not working.

    1. Finding 15days old files and delete- Working.

    2. Finding 1 Minute old log and move to log directory-Working.

    3. Finding 1 day old copied file and move to backup location.

    4. Finding files copy is completed from N/w server and send notification- send email working but finding file copy is completed or not not working.

    Please find script below.

    for point 4 i tried with below logics.

    a. Finding if any 0KB from many files if no 0kb file found send email.

    $path = "D:\test\"
    cls


    $Files = @(Get-Childitem -path $path -recurse -force )
    echo $files

    if ($Files.Length -gt 1024)
    {
    "send Email Notification}
    else
    {
    "file Not Arrived"
    }

    b. Finding if any 0KB from many files and last write time is greater than 2 hour, if no 0kb file found send email.

    $limit = (Get-Date).AddDays(-15)
    $limitmove = (Get-Date).AddDays(-1)
    $move = "P:\From Email"
    $path = "\\SSRS\TestforNotification\"
    $LogTime = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
    $LogFile = 'P:\PowershellScriptingLogs\'+"FTPDBLOG_"+$LogTime+".log"
    $LogFile1 = 'P:\PowershellScriptingLogs\'

    Get-ChildItem -Path $move -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force # Delete files older than the $limit 15 days from email folders.
    Get-Childitem -Path $LogFile1 | where-object {$_.Lastwritetime -lt (date).addminutes(-1)} | move-item -dest $move -force #move log files
    get-childitem -Path $path -recurse | where-object {$_.LastWriteTime -lt (get-date).AddDays(-1)} | move-item -destination $move -force #Move files older then one day old.
    #Get-ChildItem -Path $path -Recurse | where {$_.Lastwritetime -lt (date).addminutes(-60)} | Set-Content $LogFile # if output file contains 10 Hours olders file data then email will be triggered.
    # Get-Childitem -Path $path -recurse | where-object {$_.Lastwritetime -lt (date).addminutes(-2)} | Set-Content $LogFile 

    #Get-Childitem -Path $path -Recurse | where-object {  if(!$_.PSIsContainer -and $_.length -gt 0) { write-host (“{0} -> {1}” -f $_.FullName, $_.Length) } } | Set-Content $LogFile 

    #Get-Childitem -Path $path -Recurse | where-object {  if(!$_.PSIsContainer -and $_.length -gt 0) { Set-Content $LogFile (“{0} -> {1}” -f $_.FullName, $_.Length) } } 

    #Get-Childitem -Path $path -Recurse | where-object { if (Test-Path *) { if((Get-Item * ).length -gt 0kb) (Get-Item * ).length -gt 0kb)  {  Set-Content $LogFile (“{0} -> {1}” -f $_.FullName, $_.Length) } } }

    Get-Childitem -Path $path -Recurse | where-object {
    If (((get-item*).length -eq 0KB) -and (get-item*).length -gt 0KB)
    {
      write-host (“{0} -> {1}” -f $_.FullName, $_.Length)
    }
    Else
    {
      Set-Content $LogFile (“{0} -> {1}” -f $_.FullName, $_.Length) 
    }
    }


    if  (Test-Path $LogFile) {
    $From = "noreply@xyz.com"
    $To = "m@xyz.com"
    $SMTPServer = "LOCALHOST"
    $SMTPPort = "25"
    $Username = "************"
    $Password = "******"

    $attachment = $LogFile 
    $subject = "DB file on FTP SSRS Server"
    $body = "Hi, 

    Data from client side is sucessfully uploaded on FTP server please take necessory action as after 1 day file will get moved to location P:\From Email.

    Thanks
    Operations Team"

    $smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
    $smtp.EnableSSL = $false
    $smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
    $smtp.Send($From, $To, $subject, $body);
    }

    Can some one help me to meet this requirment using only Powershell.

    Thanks,

    MaNiSH...!!!


    MaNISH SURYAWANSHI

    Monday, February 8, 2016 10:01 AM

Answers

  • Hi All,

    Please find solution below,

    function sendemail(){
    $EmailFrom = “txyz@xyz.com”
    
    $EmailTo = “ABC@XYZ.COM”
    
    $Subject = “Notification Mail”
    
    $Body = "$_ file arrived"
    
    $SMTPServer = “mail.testing.com”
    
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25)
    
    $SMTPClient.EnableSsl = $false
    
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential('test5@testing.com', '*******');
    
    $SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
    }
    
    $path = "d:\test"
    
    $FolderList = @()
    $exclude = @()
    $FinalFiles = @()
    
    foreach($ChildFolder in Get-ChildItem -Path $path -Recurse)
    {
        if($ChildFolder.PSIsContainer)
        {
            $FolderList = $FolderList + $ChildFolder.FullName
        }
    }
    
    foreach($Folder in $FolderList)
    {
        $FileList = Get-ChildItem($Folder) -Recurse 
        
    
        foreach($File in $FileList)
        {
            if($File.Length -lt 1 -and !($File.PSIsContainer))
            {
                $exclude = $exclude + $File.Directory.FullName
                echo $exclude
            }
        }
        foreach($CorrectFile in $FileList)
        {
            if($exclude -contains $CorrectFile.Directory.FullName -and !($CorrectFile.PSIsContainer))
            {
                continue
            }
            elseif(!($CorrectFile.PSIsContainer) -and ($FinalFiles -notcontains $CorrectFile))
            {
                $FinalFiles = $FinalFiles + $CorrectFile
            }
            
        }
        
    }
    echo $FinalFiles
    $FinalFiles | %{sendemail}

    Thanks,

    MaNiSH...!!!


    MaNISH SURYAWANSHI

    • Marked as answer by MaNISHAPE Friday, February 19, 2016 1:37 PM
    Wednesday, February 17, 2016 11:54 AM

All replies

  • Hi Manish,

    well, one oddity I found in your script is that odd Where-Object thing. Try this instead:

    Get-Childitem -Path $path -Recurse | ForEach-Object {
    	If (($_.length -eq 0KB) -and ($_.length -gt 0KB))
    	{
    		write-host (“{0} -> {1}” -f $_.FullName, $_.Length)
    	}
    	Else
    	{
    		Set-Content $LogFile (“{0} -> {1}” -f $_.FullName, $_.Length)
    	}
    }

    As for the 4th point, validating file transfer: Move-Item is a synchronous operation, meaning the script will only continue when finished. You can validate success by moving file after file in a separate try/catch operation - when transfer fails, powershell will throw an error.

    Cheers,
    Fred


    There's no place like 127.0.0.1

    Monday, February 8, 2016 10:44 AM
  • When asking questions it is important to post code that is readable.   You should also remove all excess unused statements and comments.

    These lines are bad.  You are missing a quote:

    f ($Files.Length -gt 1024) {
    	"send Email Notification}
     else
     {
     "file Not Arrived"
     }

    It is also badly formatted for ease of following the code:

    if($Files.Length -gt 1024){
    	'send Email Notification'
    }else{
    	'file Not Arrived'
    }


    \_(ツ)_/

    Monday, February 8, 2016 4:10 PM
  • The following line is impossible and will always be false:

    If (((get-item*).length -eq 0KB) -and (get-item*).length -gt 0KB)

    Something cannot be equal ro zero and greater than zero at the same time except for Schrodinger's cat.


    \_(ツ)_/

    Monday, February 8, 2016 4:20 PM
  • This line is wrong;
    Get-Childitem -Path $LogFile1 | where-object {$_.Lastwritetime -lt (date).addminutes(-1)} | move-item -dest $move -force 
    

    The (date) is wrong.

    It is easier to use" [datetime].Now.AddMinutes(-1)

    It is also bad logic.  It should be "-ge"


    \_(ツ)_/

    Monday, February 8, 2016 4:33 PM
  • As an example here is a version that is readable and will be easier to debug.

    $path = 'D:\test\'
    
    $body = 'Hi, 
    
     Data from client side is sucessfully uploaded on FTP server please take necessory action as after 1 day file will get moved to location P:\From Email.
    
     Thanks
     Operations Team
    ' #'
    $mailprops = @{
    	From = 'noreply@xyz.com'
    	To = 'm@xyz.com'
    	SMTPServer = 'LOCALHOST'
    	Port = 25
    	UseSSL = $true
    	Credentials = New-Object System.Net.NetworkCredential('Username', 'Password')
    	Subject = 'DB file on FTP SSRS Server'
    	Body=$body
    }
    
    
    $files = Get-Childitem -path $path -recurse -force
    if($files.Count -gt 1024){
    	'send Email Notification'
    }else{
    	'file Not Arrived'
    }
    
    
    #b. Finding if any 0KB from many files and last write time is greater than 2 hour, 
    #if no 0kb file found send email.
    
    $limit = (Get-Date).AddDays(-15)
    $limitmove = (Get-Date).AddDays(-1)
    $move = 'P:\From Email'
    $path = '\\SSRS\TestforNotification\' #'
    $LogTime = Get-Date -Format 'MM-dd-yyyy_hh-mm-ss'
    $LogFile = 'P:\PowershellScriptingLogs\FTPDBLOG_{0}.log' f  $LogTime
    $LogFile1 = 'P:\PowershellScriptingLogs\' #'
    
    # Delete files older than the $limit 15 days from email folders.
    Get-ChildItem -Path $move -Recurse -Force | 
    	Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | 
    	Remove-Item -Force
    
    #move log files
    Get-Childitem -Path $LogFile1 | 
    	where-object {$_.Lastwritetime -lt (date).addminutes(-1)} | 
    	move-item -dest $move -force
    
    #Move files older then one day old.
    get-childitem -Path $path -recurse | 
    	where-object {$_.LastWriteTime -lt (get-date).AddDays(-1)} | 
    	move-item -destination $move -force
    
    Get-Childitem -Path $path -Recurse | 
    	ForEach-Object {
    		if($_.length -gt 0){
    	   		write-host (Length greater than zero '{0} -> {1}' -f $_.FullName, $_.Length)
    		 }else{
    		   Set-Content $LogFile ('{0} -> {1}' -f $_.FullName, $_.Length) 
    		 }
    	 }
    
    
    if(Test-Path $LogFile){
    	Send-MailMessage @mailprops -Attachments $logfile
    }
    These  "#'" are to fix bugs in the style sheet and post format logic.


    \_(ツ)_/







    • Edited by jrv Monday, February 8, 2016 4:42 PM
    Monday, February 8, 2016 4:38 PM
  • Hi All,

    Thanks for your responses little bit your help worked for me.

    Special thanks to JRV for guidance. It was first time i am using this forum.

    My issue still persist for point 4,

     function sendemail(){
    $EmailFrom = “test5@testing..com”
    
    $EmailTo = “m@testing.com”
    
    $Subject = “Notification Mail”
    
    $Body = “'$_'  file arrived ”
    
    $SMTPServer = “mail.testing.testing.com”
    
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25)
    
    $SMTPClient.EnableSsl = $false
    
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential('test5@testing.com', '*******');
    
    $SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
    }
    
    $path = "D:\test"
    #$size = Get-ChildItem -path $path -Recurse | where { $_.Length -gt 1 } | %{sendemail}
    Get-Childitem -Path $path -Recurse | 
    	ForEach-Object {
    		if($_.length -gt 0KB ) {
    	   		%{sendemail}
    		 }else{
    		   '0 KB files' #Set-Content $LogFile ('{0} -> {1}' -f $_.FullName, $_.Length) 
    		 }
    	 }
    

    From Above script can able to receive email notification for files which are more then 0KB, This is ok.

    but trying to achieve it as, even if one 0KB file is there among 5 files it should not send email notification. once all 5 files get size more then 0KB then only it should send email, no mind if it send notification after 1 hour of lastwrite time.


    MaNISH SURYAWANSHI

    Tuesday, February 9, 2016 1:42 PM
  • In that case I'd set a trigger in the else block to signify that a 0KB file was found (actually, you'd be better off switching the logic and using the if test itself for setting this trigger). Once the loop has finished, test the trigger and only send the message if you haven't set it.

    Tuesday, February 9, 2016 1:46 PM
  • Hi,

    I am new with scripting plane hardware type person. It will be great help if get the script for triggering.

    Thanks,

    MaNiSH.


    MaNISH SURYAWANSHI

    Tuesday, February 9, 2016 2:49 PM
  • Example 1:

    $trigger = $false
    
    1..5 | ForEach-Object {
    
        If ( $_ -eq 4 ) {
    
            $trigger = $true
    
        }
    
    }
    
    If ($trigger) {
    
        Write-Host 'Trigger was set' -ForegroundColor Green
    
    } Else {
    
        Write-Host 'Trigger was NOT set' -ForegroundColor Red
    
    }

    Example 2:

    $trigger = $false
    
    1..3 | ForEach-Object {
    
        If ( $_ -eq 4 ) {
    
            $trigger = $true
    
        }
    
    }
    
    If ($trigger) {
    
        Write-Host 'Trigger was set' -ForegroundColor Green
    
    } Else {
    
        Write-Host 'Trigger was NOT set' -ForegroundColor Red
    
    }


    Tuesday, February 9, 2016 2:57 PM
  • Hi,

    I tried with given trigger statements still receiving email notification when there is 0KB file among 5 Files.

    $path = "D:\test"
    $trigger = $false
    #$size = Get-ChildItem -path $path -Recurse | where { $_.Length -gt 1 } | %{sendemail}
    Get-Childitem -Path $path -Recurse 
     
    1..30 | ForEach-Object {
    		if($_.length -gt 0KB ) {
    	   		$trigger = $true
    }
    }
    If ($trigger) {
    
    		 %{sendemail}
    }
    else{
    		 '0 KB files'   
    		 }
    
    
    
    #Below is the output
    <#
       Directory: D:\test
    
    Mode                LastWriteTime     Length Name                                                                                                            
    ----                -------------     ------ ----                                                                                                            
    d----          2/9/2016   4:18 PM            testrootvd                                                                                                      
    d----          2/9/2016   9:04 PM            testrootvd - Copy                                                                                               
        Directory: D:\test\testrootvd
    Mode                LastWriteTime     Length Name                                                                                                            
    ----                -------------     ------ ----                                                                                                            
    d----          2/9/2016   9:17 PM            New folder                                                                                                      
        Directory: D:\test\testrootvd\New folder
    Mode                LastWriteTime     Length Name                                                                                                            
    ----                -------------     ------ ----                                                                                                            
    -a---          2/9/2016   4:19 PM     495616 New Microsoft Access Database.accdb                                                                             
    -a---          2/9/2016   9:17 PM          0 New Text Document.txt                                                                                           
        Directory: D:\test\testrootvd - Copy
    Mode                LastWriteTime     Length Name                                                                                                            
    ----                -------------     ------ ----                                                                                                            
    -a---          1/7/2016   7:31 PM      98757 iis-85.png                                                                                                      
    -a---          2/9/2016   4:17 PM       6186 New Microsoft Excel Worksheet.xlsx                                                                              
    
    With Email Notification...
    #>
    # Also received Email Notification.


    MaNISH SURYAWANSHI

    Tuesday, February 9, 2016 3:56 PM
  • Hi All,

    Please find solution below,

    function sendemail(){
    $EmailFrom = “txyz@xyz.com”
    
    $EmailTo = “ABC@XYZ.COM”
    
    $Subject = “Notification Mail”
    
    $Body = "$_ file arrived"
    
    $SMTPServer = “mail.testing.com”
    
    $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 25)
    
    $SMTPClient.EnableSsl = $false
    
    $SMTPClient.Credentials = New-Object System.Net.NetworkCredential('test5@testing.com', '*******');
    
    $SMTPClient.Send($EmailFrom, $EmailTo, $Subject, $Body)
    }
    
    $path = "d:\test"
    
    $FolderList = @()
    $exclude = @()
    $FinalFiles = @()
    
    foreach($ChildFolder in Get-ChildItem -Path $path -Recurse)
    {
        if($ChildFolder.PSIsContainer)
        {
            $FolderList = $FolderList + $ChildFolder.FullName
        }
    }
    
    foreach($Folder in $FolderList)
    {
        $FileList = Get-ChildItem($Folder) -Recurse 
        
    
        foreach($File in $FileList)
        {
            if($File.Length -lt 1 -and !($File.PSIsContainer))
            {
                $exclude = $exclude + $File.Directory.FullName
                echo $exclude
            }
        }
        foreach($CorrectFile in $FileList)
        {
            if($exclude -contains $CorrectFile.Directory.FullName -and !($CorrectFile.PSIsContainer))
            {
                continue
            }
            elseif(!($CorrectFile.PSIsContainer) -and ($FinalFiles -notcontains $CorrectFile))
            {
                $FinalFiles = $FinalFiles + $CorrectFile
            }
            
        }
        
    }
    echo $FinalFiles
    $FinalFiles | %{sendemail}

    Thanks,

    MaNiSH...!!!


    MaNISH SURYAWANSHI

    • Marked as answer by MaNISHAPE Friday, February 19, 2016 1:37 PM
    Wednesday, February 17, 2016 11:54 AM