Two issues I experience are,
It does the job but throws the error shown below.
The notification doesn't fire, the condition is not met at all.
gpg2.exe : gpg: encrypted with 2048-bit RSA key, ID D9A0AD5F, created
2017-07-04
At C:\Scripts\FinanceGPGDecryptor.ps1:24 char:5
+ & <<<< $gpg_prog --batch --yes --passphrase "$gpg_p" -r "$gpg_r" -o "$out_file" -d "$in_file"
+ CategoryInfo : NotSpecified: (gpg: encrypted ...ated 2017-07-04:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
"key_id>"
# Variables
$gpg_prog = "C:\Program Files (x86)\GNU\GnuPG\pub\gpg2.exe"
$sFolder = "J:\Receive\"
$dFolder = "J:\Receive\Decrypted\"
$aFolder = "J:\Receive\Archived\"
$Log = "J:\Receive\decrypt.log"
$gpg_p = "****"
$gpg_r = "key_id"
$recipients = #("alias#company.com")
$date = date;
Add-Content $Log $date;
Set-Location J:\
# gpg wrapper
function gpg_me {
$in_file = $sFolder + $args[0] + ".pgp"
$out_file = $dFolder + $args[0] + ".txt"
#Write-Host $in_file " | " $out_file
& $gpg_prog --batch --yes --passphrase "$gpg_p" -r "$gpg_r" -o "$out_file" -d "$in_file"
if (!$LastExitCode) {
Add-Content $Log "Inbound file: $in_file | Outbound file: $out_file";
Move-Item -Path $in_file -Destination $aFolder -force
#echo "all good" $LastExitCode
}
}
# Loop thru current directory.
$items = Get-ChildItem -Path $sFolder
foreach ($item in $items) {
#if the item is NOT a directory, then process it.
if ($item.Attributes -ne "Directory") {
#Write-Host "file found:" $item
if ($Output = $item -like "*.pgp") {
#Write-Host "Decrypting new file " $item "'" $Output
gpg_me $item.BaseName
} else {
# // File does not exist
# Write-Host $item.Name " is not a file for decrypting:"
}
}
}
Add-Content $Log "`n **********`n";
Write-Host "LastExitCode:" $LastExitCode
Write-Host "Output:" $Output
if ($Output -and !$LastExitCode) {
Send-MailMessage -From "noreply#compnay.com" -SmtpServer smtp.company.com -To "$recipients" -Subject "file received and decrypted" -Body "Decrypted file can be found at $dFolder" -Attachment $Log;
} else{
}
Related
I have this script that creates files using bcp. As BCP doesn't export data with header i need to join both files into. If i run the code in another script it creates the csv file but if i run this script it fails saying files DOES NOT EXIST, that is the last section of the script below (#THE PROBLEM STARTS HERE).
Appreciate any help.
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'
$bcp = 'c:\Program Files\Microsoft SQL Server\100\Tools\Binn\bcp.exe'
$delimiter = '","'
$server = 'BLABLABLA'
$database = 'DMB'
$schema = '.dbo.'
$dbschema = $database + $schema
$atresult = "#result"
$commas = " + ',','') + "
$head1 = 'Use '
$head2 = ' Declare ' # atresult
$head3 = ' varchar(max) select ' # atresult
$head4 = ' = COALESCE(' #atresult $commas
$head5 = 'COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ' # tablename
$head6 = ' select ' #atresult
$tables = #('EntityTypes_20181205','FieldFieldTypeInfo')
$output_path = 'D:\Temp\DataModelBuild\'
# Deletes any file in Destination Folder
#if ( (Get-ChildItem $output_path | Measure-Object).Count -ne 0) {}
Get-ChildItem -Path $output_path -Include *.* -File -Recurse | foreach { $_.Delete()}
foreach ($element in $tables)
{
# GET COLUMN NAMES into header file
$outputFile = $output_path + $element + ".header"
$NQ = '"' + $head1 + $database + $head2 + $atresult + $head3 + $atresult + $head4 + $atresult + $commas + $head5 + ''' + $element + ''' + $head6 + $atresult + '"'
#$arglist = "(" + $NQ + " queryout " + $outputFile + ", -S " + $server + " -T -t" + $delimiter + " -c -k)"
$arglist = #('"',
$head1,
$database,
$head2,
$atresult,
$head3,
$atresult,
$head4,
$atresult,
$commas,
$head5,
"'$element'",
$head6,
$atresult,
'"',
" queryout $outputFile",
"-S $server -T -t$delimiter -c -k")
#write-output $arglist
Start-Process -FilePath $bcp -ArgumentList $arglist
#Read-Host
# GET DATA into data file
$outElement = $dbschema + "[" + $element + "]"
$outputFile = $output_path + $element + ".data"
$arglist = #($outElement, "out $outputFile", "-S $server -T -t$delimiter -c -k")
Start-Process -FilePath $bcp -ArgumentList $arglist
#write-output $arglist
#Read-Host
# Merge header and data to csv
#Invoke-Expression "&'$ExtPs1' -FilePath $output_path -FileName $element"
#Write-Output "call "
#Invoke-Expression "&'D:\idna\PedroTemp\cp2csv.ps1' $output_path $element"
#Read-Host
#THE PROBLEM STARTS HERE
$File1 = #("$output_path$element.header")
$File2 = #("$output_path$element.data")
$File3 = #("$output_path$element.csv")
write-output $File1, $File2, $File3
If (-not (Test-Path -Path $File1)) {
Write-Error "File DOES NOT EXIST '$File1'" -ErrorAction Stop
} else {
Write-Host "File EXIST"
}
Add-Content $File3 -value (Get-Content $File1)
Add-Content $File3 -value (Get-Content $File2)
#write-output $File1, $File2, $File3 -ErrorAction Stop
Read-Host
}
My question is why isn't the script detecting the file?
Is there any problem with the string?
The strings for the pathes aren't build correctly. When you use a member in a string you have to enclose the variable and the member with $().
$File1 = "$output_path$($element.header)"
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?
I am trying to write ALL the output to a logfile, and I seem to be doing something wrong. I also need the output on the screen.
Here is what I have so far:
# Log file time stamp:
$LogTime = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
# Log file name:
$LogFile = "EXPORTLOG_"+$LogTime+".log"
$database = "DB"
$schema = "dbo"
$table = "TableName"
foreach($line in Get-Content .\Alltables.txt) {
if($line -match $regex){
$bcp = "bcp $($database).$($schema).$($line) out $line.dat -T -c"
Invoke-Expression $bcp | Out-File $LogFile -Append -Force
}
}
When I want to write out the command to the logfile so I know which table is processed, I get an error:
Here is the code:
# Log file time stamp:
$LogTime = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
# Log file name:
$LogFile = "EXPORTLOG_"+$LogTime+".log"
$database = "DB"
$schema = "dbo"
$table = "TableName"
foreach($line in Get-Content .\Alltables.txt) {
if($line -match $regex){
$bcp = "bcp $($database).$($schema).$($line) out $line.dat -T -c" | Out-File $LogFile -Append -Force
Invoke-Expression $bcp | Out-File $LogFile -Append -Force
}
}
And the error:
Invoke-Expression : Cannot bind argument to parameter 'Command' because it is null.
At C:\Temp\AFLAC\export.ps1:16 char:21
+ Invoke-Expression $bcp | Out-File $LogFile -Append -Force
+ ~~~~
+ CategoryInfo : InvalidData: (:) [Invoke-Expression], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.InvokeExpressionCommand
I am obviously not very good with Powershell and I please need your advise on how I should code this the best possible way.
Maybe the above way is completely wrong, I do appreciate your guidance.
Thank you
Try modifying your code to something like this:
foreach($line in Get-Content .\Alltables.txt) {
if($line -match $regex) {
$bcp_command = "bcp $database" + '.' + $schema '.' + $line + ' out ' + $line + '.dat -T -c')
Tee-Object -FilePath $LogFile -InputObject $bcp_command -Append
$bcp_results = Invoke-Expression $bcp_command
Tee-Object -FilePath $LogFile -InputObject $bcp_results -Append
}
}
I have a PowerShell script that looks for a file in a folder and moves it to another folder, and renames the file with a date extension.
Like this:
$a = "\\server\Users\Desktop\why agile.docx"
$f = "\\server\Users\desktop\Archive\why agile.docx"
Move-item $a $f
Function renameFile ($location, $filename, $extension)
{
$d = get-date -uformat "%Y%m%d"
$old = $location + $filename + $extension
$new = $filename + "_" + $d + $extension
rename-item $old $new
}
renamefile -location "\\server\Users\desktop\Archive\" -filename "why agile" -extension ".docx"
My question is: How can I add to this script to email out any error messages, or if there are missing files, duplicate files or if the process fails for some reason (time out, etc...)?
Thanks,
Clear the $Error automatic variable and set $ErrorActionPreference to SilentlyContinue before you start. Send an e-mail with the content of the $Error variable if it's not empty after you finished:
$Error.Clear()
$eap = $ErrorActionPreference
$ErrorActionPreference = 'SilentlyContinue'
renamefile ...
if ($Error) {
Send-MailMessage -From $sender -To $recipient -Body ($Error -join "`n") ...
}
$ErrorActionPreference = $eap
For taking care of missing or duplicate files add appropriate checks.
To expand on the other answer, you can wrap your code in a try block and then in your catch block, email the errors.
Something like
try {
rename file ...
}
catch [Exception] {
Send-MailMessage ...
}
Here's what I ended up doing. I used the try { } catch { } and it works great. Thanks to everyone for helping...it got me pointed in the right direction. I'm an newbie with Powershell.
try
{
$a = "\\servername\Users\Desktop\agile.docx"
$b = "\\servername\Users\Desktop\Archive\agile.docx"
Move-item $a $b -ErrorAction stop
Function renameFile ($location, $filename, $extension)
{
$d = get-date -uformat "%Y%m%d"
$old = $location + $filename + $extension
$new = $filename + "_" + $d + $extension
rename-item $old $new
}
renamefile -location "\\servername\Users\desktop\Archive\" -filename "Agile" -extension ".docx"
}
Catch
{
$ErrorMessage = $_.Exception.Message
$FailedItem = $_.Exception.ItemName
Send-MailMessage -From my.name#mycompany.com -To her.name#mycompany.com -Subject "Files Failed to Transfer to Archive Folder!" -SmtpServer smtp... -Body "The error message is: '$ErrorMessage'"
Break
}
I want to take a text file with usernames, and then search a specific location (UNC path) and return any matches found, outputting them to a log file:
#Searches target folder for all folders matching input
$start = (get-date -uformat "%Y-%m-%d_%H%M")
$defaultLogFileName = "folder_matcher" + $start + ".log"
#Log file header
$header = #()
$header += "=============================="
$header += "Search results"
$header += ""
$header += "Execution Start: " + (get-date -uformat "%Y-%m-%d %H%M") + ""
$header += ""
#Get the logfile location
do
{
$logdir = Read-Host "Enter log directory (or press Enter for default c:\)"
if ($logdir -eq "")
{$logfile = ("c:\" + $defaultLogFileName); break;}
if(Test-Path $logdir)
{$logfile += ($logdir + "\" + $defaultLogFileName); break;}
Write-Host -ForegroundColor Red "Directory does not exist"
} while (!(Test-Path $logfile))
$SourceFile = Read-Host "Enter file path"
$SearchValue = Read-host "Enter target directory to sweep"
$header | Out-File -FilePath $logfile
foreach($user in $sourcefile){
Get-ChildItem $SearchValue -filter $user | Out-file -Append -FilePath $logfile
}
When I attempt to use Get-ChildItem in this loop, this is the result:
Get-ChildItem : Second path fragment must not be a drive or UNC name.
Parameter name: path2
At \\erebus\erebus_users$\rraymond1\ps\searchandmatch.ps1:32 char:14
+ Get-ChildItem <<<< $SearchValue -filter $user | Out-file -Append -FilePath $logfile
+ CategoryInfo : InvalidArgument: (\\harvard\tsprofiles$:String)
[Get-ChildItem], ArgumentException + FullyQualifiedErrorId DirArgumentError,Microsoft.PowerShell.Commands.GetChildItemCommand
I have tried replacing the variables with fixed values (even mapping the UNC path locally and trying to run it that way), and the problem remains. How can I fix it?