By Charles McDowell
Comptia Certified Linux Networking Professional.
Cisco Certified Networking Technician.
Microsoft Technology Associate Database Administration
A Collection of Useful power shell scripts.
#How to Download from a file transfer protocol server. ## Script configuration #$BackupPath = "\\Servername\DATAFOlder\DatabaseName\FTPHandling\HOLD" $ScriptPath = "\\Servername\DATAFOlder\DatabaseName\FTPHandling" $WorkingPath = "\\Servername\DATAFOlder\DatabaseName\FTPHandling\WORK" ## SQL configuration $DatabaseInstance = "ServerName, Portnumber" $Database = "Databasename" ## SFTP Settings $Key = (array of numbers) $SFTPSite = "ftp.nameofftpsite.com" $SFTPSSHKey = "ssh-rsa key" $SFTPPassword = Get-Content "$ScriptPath\ftp.txt" | ConvertTo-SecureString -Key $Key #Created via: read-host -assecurestring | convertfrom-securestring -Key $Key| out-file $Scriptpath\olhsftp.txt $SFTPCredentials = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList abccompanyint, $SFTPPassword ##SMTP Settings (For error notifications) $SMTPServer = "mail.yoursmtpserver.com" $SMTPFrom = "youremail@yoursmtpserver.com" $ErrorMessageRecepient = "insert monitored email" $ErrorSubject = "Error downloading files from FTP" ## Import the WinSCP module Import-Module -Name WinSCP Import-Module SqlServer ## Connect to the FTP server $Session = New-WinSCPSession -Credential $SFTPCredentials -HostName $SFTPSite -Protocol Sftp -SshHostKeyFingerprint $SFTPSSHKey -ErrorAction Stop ## Check for expected incoming files and download them if they are available. $ExpectedFiles = ( Invoke-Sqlcmd -ServerInstance $SFPInstance -Database $SFPDatabase -Query "EXEC [Staging].[FTPGetFiles]" ) $ExpectedFiles | Add-Member NoteProperty -Name AvailableFiles -Value $null ## Only look for files from ftp.yourftpserver.com $ExpectedFiles = $ExpectedFiles | WHERE {$_.FTPSite -eq 'ftp.yourftpserver.com'}; try{ ForEach ($ExpectedFile in $ExpectedFiles) { $ExpectedFile.AvailableFiles = Get-WinSCPItem -WinSCPSession $Session -Path $ExpectedFile.FTPPath -Filter * ForEach ($AvailableFile in $ExpectedFile.AvailableFiles){ If($AvailableFile.Name -match $ExpectedFile.ExpectedFileName ){ #Receive-WinSCPItem -WinSCPSession $Session -Path $AvailableFile -Destination $BackupPath -ErrorAction Stop | Out-Null Receive-WinSCPItem -WinSCPSession $Session -Path $AvailableFile -Destination $ExpectedFile.Destination -ErrorAction Stop | Out-Null Receive-WinSCPItem -WinSCPSession $Session -Path $AvailableFile -Destination $WorkingPath -Remove -ErrorAction Stop | Out-Null } } } } catch{ Send-MailMessage -From $SMTPFrom -To $ErrorMessageRecepient -SmtpServer $SMTPServer -Subject $ErrorSubject -Body "The C:\ScriptFolder\FTPRetrieval\DownloadFTPFiles.ps1 routine on ServerName encountered a problem downloading files from the SFTP server. ERROR MESSAGE: $Error" } Exit
#How to Handle files from ftp ## Script configuration $ScriptPath = "\\Servername\DATAFOlder\DatabaseName\FTPHandling" $WorkingPath = "\\Servername\DATAFOlder\DatabaseName\FTPHandling\WORK" ## SQL configuration $SFPInstance = "ServerName, Port Number" $SFPDatabase = "DatabaseName" ##SMTP Settings (For error notifications) $SMTPServer = "mail.yoursmtpserver.com" $SMTPFrom = "Email@yoursmtpserver.com" $ErrorMessageRecepient = "Monitored email" $ErrorSubject = "Error handling file: $file" Import-Module -name \\Servername\DATAFOlder\DatabaseName\DataTools.psm1 -Global -Force Import-Module SqlServer Set-Location $WorkingPath $Files = Get-ChildItem $WorkingPath $Files = $Files | Where-Object {$_ -NotLike "*.filepart*"} $ExpectedFiles = ( Invoke-Sqlcmd -ServerInstance $DatabaseInstance -Database $Database -Query "Stored proceedure to get the fles" ) try{ ForEach ($File in $Files) { ForEach ($ExpectedFile in $ExpectedFiles) { If ( $File.Name -match $ExpectedFile.ExpectedFileName ) { If ([string]::IsNullOrWhiteSpace($ExpectedFile.FileHandling)) { Switch -Wildcard ($File.Name) { *.csv { Copy-Item $File -Destination $ExpectedFile.Destination -Force -ErrorAction Stop; Remove-Item $File.FullName -Force; Set-Location $WorkingPath} *.txt { Copy-Item $File -Destination $ExpectedFile.Destination -Force -ErrorAction Stop; Remove-Item $File.FullName -Force; Set-Location $WorkingPath } *.pgp { DecryptPgP -EncryptedFile $File.Fullname -DecryptedFile (Join-Path -Path $ExpectedFile.Destination -ChildPath $File.BaseName) | Out-Null; Remove-Item $File.FullName -Force; Set-Location $WorkingPath } *.gpg { DecryptPgP -EncryptedFile $File.FullName -DecryptedFile (Join-Path -Path $ExpectedFile.Destination -ChildPath $File.BaseName) | Out-Null; Remove-Item $File.FullName -Force; Set-Location $WorkingPath } *.zip { Copy (Test-Path $File) { ExtractArchive -ProcessingDir $WorkingPath -File $File -Output $ExpectedFile.Destination; Remove-Item $File -Force -ErrorAction Stop; Set-Location $WorkingPath }} *.json { Copy-Item $File -Destination $ExpectedFile.Destination -Force -ErrorAction Stop; Remove-Item $File.FullName -Force; Set-Location $WorkingPath } } } Else { Invoke-Expression $ExpectedFile.FileHandling } $CustomerFileTypeKey = $ExpectedFile.CustomerFileTypeKey Invoke-Sqlcmd -ServerInstance $SFPInstance -Database $SFPDatabase -Query "EXEC dbo.usp_InsertFile $CustomerFileTypeKey, '$File'" } } } } catch{ Send-MailMessage -From $SMTPFrom -To $ErrorMessageRecepient -SmtpServer $SMTPServer -Subject $ErrorSubject -Body "The 'insert script file location' routine on 'insert server name' encountered a problem extracting, decrypting or moving $file to the output directory ERROR MESSAGE: $Error" } Exit
#How to move files for Marketing campaign ## Script configuration $ScriptPath = "C:\Scripts\LCOMM" $FileSource = "\\Servername\DATAFOlder" $FileDestination = "\\destinationServername\destinationDATAFOlder" ##SMTP Settings (For error notifications) $SMTPServer = "mail.yoursmtpserver.com" $SMTPFrom = "email@yoursmtpserver.com" $ErrorMessageRecepient = "monitored email" $ErrorSubject = "Error moving file: $file" $Recipient = "their email" $Subject = "SECURE: File For Review" Set-Location $FileSource $Files = Get-ChildItem $FileSource try{ ForEach ($File in $Files) { Switch -Wildcard ($File) { filename*.txt { If (Test-Path $File) { Send-MailMessage -Attachments $File -From $SMTPFrom -To $Recipient -CC "ADD email" -SmtpServer $SMTPServer -Subject $Subject -Body "New data have been identified and added to $file. Attached for your review." -ErrorAction Stop; Remove-Item $File -Force -ErrorAction Stop;}} Filename1*.txt { If (Test-Path $File) { Move-Item -Path $File -Destination $FileDestination -Force -ErrorAction Stop;}} Filename2*.txt { If (Test-Path $File) { Move-Item -Path $File -Destination $FileDestination -Force -ErrorAction Stop;}} Filename3*.txt { If (Test-Path $File) { Move-Item -Path $File -Destination $FileDestination -Force -ErrorAction Stop;}} Filename4*.txt { If (Test-Path $File) { Move-Item -Path $File -Destination $FileDestination -Force -ErrorAction Stop;}} Filename5*.txt { If (Test-Path $File) { Move-Item -Path $File -Destination $FileDestination -Force -ErrorAction Stop;}} } } } catch{ Send-MailMessage -From $SMTPFrom -To $ErrorMessageRecepient -SmtpServer $SMTPServer -Subject $ErrorSubject -Body "There was a problem moving $file to pickup directory ERROR MESSAGE: $Error" } Exit
#How to run SQL Scripts and limit to specific stored proceedures Import-Module SqlServer ## SQL configuration $Instance = "Servername, Port number" $Database = "Database Name" ## Scripts file location path $ScriptDIR = "\\ServerName\datafolder\Scripts\" $SQLScriptDIR = "\\ServerName\datafolder\Scripts\sqlscripts\ProcessScripts\Environment\" $SQLScriptArchive = "\\ServerName\datafolder\Scripts\sqlscripts\ScriptsArchive\Environment\" $SQLScriptNotApproved = "\\ServerName\datafolder\Scripts\sqlscripts\ScriptsArchive\NotApproved\" $ApprovedSQLScripts = @('Sproc 1', 'Sproc 2', 'Sproc 3','Sproc 4','Sproc 5') $InvalidContent = @('INSERT INTO', 'ALTER TABLE','Delete From','DROP DATABASE','CREATE DATABASE ','BACKUP DATABASE','Create View','CREATE OR REPLACE VIEW','DROP VIEW','Update\s.*..*\n*set.') # Check for sql scripts in the folder $SQLScripts = Get-ChildItem -Path $SQLScriptDIR If ([string]::IsNullOrWhitespace($SQLScripts)){ Exit Write-Host "No Scripts in $SQLScriptDIR" } $SQLScripts | Add-Member -NotePropertyName ProcessingStatus -NotePropertyValue '' $ApprovedSQLScripts = @() <# Email notifying the list of Script that was processed succesfully, Scripts not processed succesfully with errors.#> ## Email setup $to = "your email", "stake holder 1", "stake holder 2", "stake holder 3","stake holder 4" $smtp = "mail.yoursmtpserver.com" $from = "your email" $subject = "SQL Scripts recently ran" $body = "Hello All, <br>" $body += "The following scripts have been ran." $body += '<style> table table, th, td { border: 1px solid black; border-collapse: collapse; } th, td { padding: 15px; text-align: left; } table#t01 tr:nth-child(even) { background-color: #eee; } table#t01 tr:nth-child(odd) { background-color: #fff; } table#t01 th { background-color: black; color: white; } </style> </head> <body> <h1>Configuration Script Status </h1> <table id="t01"><tr><th>Filename</th> <th>Status</th></tr>' # Verify script content and mark approved scripts. ForEach($Script in $SQLScripts | Where-Object -Property ProcessingStatus -NE "Not Approved") { $Script.ProcessingStatus = 'Not Processed' ForEach( $Statement in $ApprovedSQLScripts){ try{ If( Get-Item $Script.FullName | Select-String -SimpleMatch $Statement ){ Write-Host "$Script contains $Statement" Write-Host "Executing Script" Invoke-Sqlcmd -ServerInstance $Instance -Database $Database -InputFile $Script.FullName $Scriptname = $Script.FullName $Script.ProcessingStatus = 'Script Executed' Write-Host "$Script.ProcessingStatus" $body += "<tr><td>$Script</td><td>Executed Successfully</td></tr>" } } catch{ $Script.ProcessingStatus = "Error" } } If( $Script.ProcessingStatus -eq 'Script Executed' ){ Move-Item -Path $Script.FullName -Destination ($SQLScriptArchive + $Script.Name) -Force } elseif( $Script.ProcessingStatus -eq "Error" ){ $body +="<tr><td>$Scriptname</td><td> Failed in SQl Server with an error of:" + $Error + "</td></tr>" Move-Item -Path $Script.FullName -Destination ($SQLScriptNotApproved + $Script.Name) -Force } } # Verify script content and mark un-approved scripts. $SQLScripts2 = Get-ChildItem -Path $ConfigurationSQLScriptDIR $SQLScripts2 | Add-Member -NotePropertyName ProcessingStatus -NotePropertyValue '' ForEach( $Script in $SQLScripts2 ) { $Script.ProcessingStatus = 'Not Processed' ForEach( $Statement in $InvalidContent ){ try{ If ( Get-Item $Script.FullName | Select-String -SimpleMatch $Statement ){ Write-Host "$Script contains $Statement" Write-Host "Script not approved" $Script.ProcessingStatus = 'Not Approved' $body += "<tr><td>$Script</td><td>Not Approved</td></tr>" Move-Item -Path $Script.FullName -Destination ($SQLScriptNotApproved + $Script.Name) -Force } } catch{ $Script.ProcessingStatus = "Error" } } } #Verify all scripts moved. $SQLScripts3 = Get-ChildItem -Path $ConfigurationSQLScriptDIR $SQLScripts3 | Add-Member -NotePropertyName ProcessingStatus -NotePropertyValue '' ForEach( $Script in $SQLScripts3 ) { try{ Write-Host "$Script does not appear to be using an approved stored proceedure." Write-Host "Script is not recognized." $Script.ProcessingStatus = 'Not Approved' $body += "<tr><td>$Script</td><td>Not Approved</td></tr>" Move-Item -Path $Script.FullName -Destination ($SQLScriptNotApproved + $Script.Name) -Force } catch{ $Script.ProcessingStatus = "Error" } } $SQLScripts | Select-Object Name, ProcessingStatus $SQLScripts2 | Select-Object Name, ProcessingStatus $SQLScripts3 | Select-Object Name, ProcessingStatus # Close table in email $body += "</table> <br><br>" # Send email. send-MailMessage -SmtpServer $smtp -To $to -From $from -Subject $subject -Body $body -BodyAsHtml -Priority high Write-Host $body Exit
#How to remove all files older than specified limit. $limit = (Get-Date).AddDays(-365) $path = "file path" # Get list of files older than the $limit. $Files = Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } # Measure the size of the files $TotalSize = ($files | Measure-Object -Sum Length).Sum / 1GB # Remove the files $Files | Remove-Item -Force # Delete any empty directories left behind after deleting the old files. Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.PSIsContainer -and (Get-ChildItem -Path $_.FullName -Recurse -Force | Where-Object ) -eq $null }| Remove-Item -Force -Recurse Write-Host " $TotalSize GB of data has been removed"