on a local Server I've got a bunch of sub-folders containing PowerShell-scripts, one of those is "sqlserver" folder contains Microsoft sqlserver module. I've got a daily task-scheduler job connecting a sql-server, there is a zip-file having the same sub-folder structure (with a folder: sqlserver) as on the local server.
The idea is to overwrite the local folder structure with the new structure from the zip-file.
The problem is the module "sqlserver" which I need to connect to sql server and get the zip file etc. Trying to overwrite it I get an error. I've tried to remove-module but it doesn't work as well.
The code:
try
{
[decimal]$lokaleVersion = 3.01 #
$deploymentVersion = 0
[string]$filetype = 'PS'
if($zipObject = Get-ZIPFile -lokaleAdminDBVersion $lokaleVersion -filetype $filetype -build 0)
{
$deploymentVersion = $zipObject.aktScriptVersion
if($deploymentVersion -gt $lokaleVersion)
{
Remove-Module -name sqlserver -Force
Unzip-File -zipObject $zipObject -zipname $filetype -modulePath $modulePath #error Access denied
$SubFolders = dir ($modulePath) | Where-Object {($_.PSIsContainer) -and ($_.Name -ne "sqlserver")} | ForEach-Object -Process {$_.FullName} -ErrorAction Stop
Import-Module -Name sqlserver -DisableNameChecking -Force
ForEach ($Folder in $SubFolders)
{
try
{
$a = (join-path -Path $modulePath -ChildPath ($folder.Split("\")[-1]) -Resolve) + "\" + "installer.ps1"
if(Test-Path ($a))
{
& $a
}
}
catch
{
Write-LogFile -Message $($Error[0].exception.message) -severity Fehler -modul $module
}
}
}
}
}
catch
{
if ($error[0].exception.message) {$message = $error[0].exception.message}
Write-LogFile -Message $message -severity Fehler -modul $module
}
It's important to overwrite the sub-folders (I'm updating the scripts) and the sqlserver-module should be updated regularly.
Thanks for your help.
Related
I am trying to install SqlServer via DSC, but I keep hitting this error
Exception calling "NewScriptBlock" with "1" argument(s): "At line:10 char:5
+ Import-DscResource -ModuleName 'SqlServerDsc'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Could not find the module 'SqlServerDsc'.
At line:438 char:9
+ SqlSetup 'InstallDefaultInstance'
+ ~~~~~~~~
My DSC configuration snippet looks like this
Configuration InstallSoftware
{
param
(
$ComputerNames
)
Import-DSCResource -ModuleName PSDesiredStateConfiguration
Import-DSCResource -Module SqlServerDsc
Node $ComputerNames
{
WindowsFeature 'NetFramework45'
{
Name = 'NET-Framework-45-Core'
Ensure = 'Present'
}
SqlSetup 'SqlInstall'
{
InstanceName = 'localhost\mssql2019'
Features = 'SQLENGINE'
Action = 'Install';
SourcePath = 'C:\SQL2019'
SQLSysAdminAccounts = #('Administrators')
DependsOn = '[WindowsFeature]NetFramework45'
}
}
InstallSoftware
I am quite positive that the SqlServer has been installed in the remote server.
Get-DscResource -Module SqlServerDsc returned the list of resources
And the folder exists in C:\Program Files\WindowsPowerShell\Modules\SqlServerDsc
Any feedback/advice is highly appreciated.
Thank you so much for your time.
Looks like this was already answered, and I'm not sure I'm following everything, but I'll typically create a wrapper function for copying resources around. Something like below with flags for specifying path, server, credential, then helper stuff like changing max envelop size (if you haven't hit this, you will) and copying out my cert. Below isn't the whole thing, but it'd at least make sure your module would copy.
{
Param (
[Parameter(Mandatory=$true)]
[string]$localpath,
[Parameter(Mandatory=$true)]
[string]$ServerName,
[Parameter(Mandatory=$true)]
[PsCredential]$PsAdmin,
[Parameter(Mandatory=$true)]
[boolean]$MaxEnvelope,
[boolean]$CopyDscResources,
[boolean]$RunDscTest,
[boolean]$AddEncryptionCert
)
#Create Path if it doesnt exist
if (!(test-path -path $localpath)) {
New-Item -ItemType directory -Path $localpath
}
if ($MaxEnvelope -eq $true)
{
$so = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$session = New-PSSession -ComputerName $ServerName -Credential $PsAdmin -SessionOption $so
Invoke-Command -Session $session -ScriptBlock {
Set-Item -Path WSMan:\localhost\MaxEnvelopeSizeKb -Value 3072
}
}
if ($CopyDscResources -eq $true)
{
$so = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
$session = New-PSSession -ComputerName $ServerName -Credential $PsAdmin -SessionOption $so
$paramsDefender = #{
Path = 'C:\Program Files\WindowsPowerShell\Modules\SqlServerDsc'
Destination = 'C:\Program Files\WindowsPowerShell\Modules'
ToSession = $session
}
Copy-Item #paramsDefender -Recurse -Force
}
$Session2 = New-CimSession -ComputerName $ServerName.ToString() -Credential $PsAdmin
Set-DscLocalConfigurationManager -Path $localpath -CimSession $Session2 -Force
Start-DSCConfiguration -Path $localpath -Cimsession $Session2 -Wait -Force -ErrorAction Stop -Verbose
if ($RunDscTest)
{
Test-DSCConfiguration -Path $localpath -Cimsession $Session2 -Verbose | Format-Table -AutoSize
}
}
#Example run
RunRemoteDsc $localpath 'Some-Server' $PsLocalAdmin $false $true $false
I have installed solr 7.5 using powershell script.
This script is able to install the solr but not able to start.solr is installing but in the start step it fails.
I have tried manually to start the service also it throws error. (unable to start solr. please contact your administrator)
i'm using java version 201 (note also i checked with 212).
I have added the script that I have used.
Param(
$solrVersion = "7.5.0",
$installFolder = "E:\solr\solr-7.5.0",
$solrPort = "8986",
$solrHost = "solr",
$solrSSL = $true,
$nssmVersion = "2.24",
$JREVersion = "1.8.0_201"
)
$JREPath = "C:\Program Files (x86)\Java\jre$JREVersion" ## Note that if you're running 32bit java, you will need to change this path
$solrName = "solr-$solrVersion"
$solrRoot = "$installFolder\$solrName"
$nssmRoot = "$installFolder\nssm-$nssmVersion"
$solrPackage = "https://archive.apache.org/dist/lucene/solr/$solrVersion/$solrName.zip"
$nssmPackage = "https://nssm.cc/release/nssm-$nssmVersion.zip"
$downloadFolder = "~\Downloads"
## Verify elevated
## https://superuser.com/questions/749243/detect-if-powershell-is-running-as-administrator
$elevated = [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544")
if($elevated -eq $false)
{
throw "In order to install services, please run this script elevated."
}
function downloadAndUnzipIfRequired
{
Param(
[string]$toolName,
[string]$toolFolder,
[string]$toolZip,
[string]$toolSourceFile,
[string]$installRoot
)
if(!(Test-Path -Path $toolFolder))
{
if(!(Test-Path -Path $toolZip))
{
Write-Host "Downloading $toolName..."
Start-BitsTransfer -Source $toolSourceFile -Destination $toolZip
}
Write-Host "Extracting $toolName to $toolFolder..."
Expand-Archive $toolZip -DestinationPath $installRoot
}
}
# download & extract the solr archive to the right folder
$solrZip = "$downloadFolder\$solrName.zip"
downloadAndUnzipIfRequired "Solr" $solrRoot $solrZip $solrPackage $installFolder
# download & extract the nssm archive to the right folder
$nssmZip = "$downloadFolder\nssm-$nssmVersion.zip"
downloadAndUnzipIfRequired "NSSM" $nssmRoot $nssmZip $nssmPackage $installFolder
# Ensure Java environment variable
$jreVal = [Environment]::GetEnvironmentVariable("JAVA_HOME", [EnvironmentVariableTarget]::Machine)
if($jreVal -ne $JREPath)
{
Write-Host "Setting JAVA_HOME environment variable"
[Environment]::SetEnvironmentVariable("JAVA_HOME", $JREPath, [EnvironmentVariableTarget]::Machine)
}
# if we're using HTTP
if($solrSSL -eq $false)
{
# Update solr cfg to use right host name
if(!(Test-Path -Path "$solrRoot\bin\solr.in.cmd.old"))
{
Write-Host "Rewriting solr config"
$cfg = Get-Content "$solrRoot\bin\solr.in.cmd"
Rename-Item "$solrRoot\bin\solr.in.cmd" "$solrRoot\bin\solr.in.cmd.old"
$newCfg = $newCfg | % { $_ -replace "REM set SOLR_HOST=192.168.1.1", "set SOLR_HOST=$solrHost" }
$newCfg | Set-Content "$solrRoot\bin\solr.in.cmd"
}
}
# Ensure the solr host name is in your hosts file
if($solrHost -ne "localhost")
{
$hostFileName = "c:\\windows\system32\drivers\etc\hosts"
$hostFile = [System.Io.File]::ReadAllText($hostFileName)
if(!($hostFile -like "*$solrHost*"))
{
Write-Host "Updating host file"
"`r`n127.0.0.1`t$solrHost" | Add-Content $hostFileName
}
}
# if we're using HTTPS
if($solrSSL -eq $true)
{
# Generate SSL cert
$existingCert = Get-ChildItem Cert:\LocalMachine\Root | where FriendlyName -eq "$solrName"
if(!($existingCert))
{
Write-Host "Creating & trusting an new SSL Cert for $solrHost"
# Generate a cert
# https://learn.microsoft.com/en-us/powershell/module/pkiclient/new-selfsignedcertificate?view=win10-ps
$cert = New-SelfSignedCertificate -FriendlyName "$solrName" -DnsName "$solrHost" -CertStoreLocation "cert:\LocalMachine" -NotAfter (Get-Date).AddYears(10)
# Trust the cert
# https://stackoverflow.com/questions/8815145/how-to-trust-a-certificate-in-windows-powershell
$store = New-Object System.Security.Cryptography.X509Certificates.X509Store "Root","LocalMachine"
$store.Open("ReadWrite")
$store.Add($cert)
$store.Close()
# remove the untrusted copy of the cert
$cert | Remove-Item
}
# export the cert to pfx using solr's default password
if(!(Test-Path -Path "$solrRoot\server\etc\solr-ssl.keystore.pfx"))
{
Write-Host "Exporting cert for Solr to use"
$cert = Get-ChildItem Cert:\LocalMachine\Root | where FriendlyName -eq "$solrName"
$certStore = "$solrRoot\server\etc\solr-ssl.keystore.pfx"
$certPwd = ConvertTo-SecureString -String "secret" -Force -AsPlainText
$cert | Export-PfxCertificate -FilePath $certStore -Password $certpwd | Out-Null
}
# Update solr cfg to use keystore & right host name
if(!(Test-Path -Path "$solrRoot\bin\solr.in.cmd.old"))
{
Write-Host "Rewriting solr config"
$cfg = Get-Content "$solrRoot\bin\solr.in.cmd"
Rename-Item "$solrRoot\bin\solr.in.cmd" "$solrRoot\bin\solr.in.cmd.old"
$newCfg = $cfg | % { $_ -replace "REM set SOLR_SSL_KEY_STORE=etc/solr-ssl.keystore.jks", "set SOLR_SSL_KEY_STORE=$certStore" }
$newCfg = $newCfg | % { $_ -replace "REM set SOLR_SSL_KEY_STORE_PASSWORD=secret", "set SOLR_SSL_KEY_STORE_PASSWORD=secret" }
$newCfg = $newCfg | % { $_ -replace "REM set SOLR_SSL_TRUST_STORE=etc/solr-ssl.keystore.jks", "set SOLR_SSL_TRUST_STORE=$certStore" }
$newCfg = $newCfg | % { $_ -replace "REM set SOLR_SSL_TRUST_STORE_PASSWORD=secret", "set SOLR_SSL_TRUST_STORE_PASSWORD=secret" }
$newCfg = $newCfg | % { $_ -replace "REM set SOLR_HOST=192.168.1.1", "set SOLR_HOST=$solrHost" }
$newCfg | Set-Content "$solrRoot\bin\solr.in.cmd"
}
}
# install the service & runs
$svc = Get-Service "$solrName" -ErrorAction SilentlyContinue
if(!($svc))
{
Write-Host "Installing Solr service"
&"$installFolder\nssm-$nssmVersion\win64\nssm.exe" install "$solrName" "$solrRoot\bin\solr.cmd" "-f" "-p $solrPort"
$svc = Get-Service "$solrName" -ErrorAction SilentlyContinue
}
if($svc.Status -ne "Running")
{
Write-Host "Starting Solr service"
Start-Service "$solrName"
}
# finally prove it's all working
$protocol = "http"
if($solrSSL -eq $true)
{
$protocol = "https"
}
Invoke-Expression "start $($protocol)://$($solrHost):$solrPort/solr/#/"
Please find the screenshot
Set JAVA_HOME environment variable and try to start Solr manualy .
Need to verify the
Set the JAVA_Home environment variable or not.
Check JRE Path in the script file (jre$JREVersion", jre-$JREVersion").
Hi i am quite frustrated with powershell. i want to use my powershell script to call another powershell script inside it.
My powershell only do the first part which is download files and does not invoke the following powershell script...
Can not think the reason behind it.. Could anyone help me with that? Thanks!
The Program looks like :
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
Set-Location $directorypath
if ($StepNumber -ne 2) {
$MyName = $MyInvocation.InvocationName
$LogFileName = ".\Logs\" + [System.IO.Path]::GetFileNameWithoutExtension($MyName) + [String]::Format("_{0:yyyy-MM-dd_HH-mm-ss}.Log", (Get-Date))
if (!(Test-Path ".\Logs")) {
$X = New-Item -path . -name Logs -ItemType directory
}
&PowerShell.exe -noProfile -File NSCCMPIDDownload.ps1 2 *>`&1 | Tee $LogFileName
exit
}
## ## ---- STEP2 ------------DownLoad the file from Website
$ErrorActionPreference = "Continue"
Write-Host Running NSCC-MPID-Download at $(Get-Date)
Write-Host ""
## Download the NSCC-MPID-Directory.xls from website
$datestr=$(Get-Date).ToString("yyyy-MM-dd")
$url="http://www.dtcc.com/~/media/Files/Downloads/client-center/NSCC/NSCC-MPID-Directory.xls"
$destination = $directorypath +"/NSCC-MPID-Directory"+"_"+$datestr+".xls"
## if destination does not exsist, creat a new one.
if (!(Test-Path $destination) ) {
New-Item $destination -type file -force
}
$client = new-object System.Net.WebClient
$client.DownloadFile( $url, $destination)
Write-Host Running NSCCMPIDInsertion.ps1
$cmd = "$directorypath\NSCCMPIDInsertion.ps1"
Invoke-Expression "$cmd"
Write-Host Running NSCCMPIDAfterParse.ps1
$cmd = "$directorypath\NSCCMPIDAfterParse.ps1"
Invoke-Expression "$cmd"
Write-Host --------------------------------------------------------------------------
Write-Host Process ended at $(Get-Date)
i am running a powershell program to insert the data from Excel to database:
param([int]$StepNumber=1)
$invocation = (Get-Variable MyInvocation).Value
$directorypath = Split-Path $invocation.MyCommand.Path
$datestr=$(Get-Date).ToString("yyyy-MM-dd")
$url="http://www.dtcc.com/~/media/Files/Downloads/client-center/NSCC/NSCC-MPID-Directory.xls"
$destination = $directorypath +"/NSCC-MPID-Directory"+"_"+$datestr+".xls"
## if destination does not exsist, creat a new one.
if (!(Test-Path $destination) ) {
New-Item $destination -type file -force
}
$client = new-object System.Net.WebClient
$client.DownloadFile( $url, $destination)
$filepath = $destination
$excelConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$filepath;Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1'"
$sqlConnection = 'Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=SIAC;Data Source=database1;'
$excelQuery = 'select * from [OTC$]'
$tablename = 'NSCC_MPID_OTC'
Try {
$conn = New-Object System.Data.OleDb.OleDbConnection($excelConnection)
$conn.open()
$cmd = $conn.CreateCommand()
$cmd.CommandText = $excelQuery
$rdr = $cmd.ExecuteReader()
$sqlbc = New-Object System.Data.SqlClient.SqlBulkCopy($sqlConnection, [System.Data.SqlClient.SqlBulkCopyOptions]::TableLock)
$sqlbc.DestinationTableName = $tableName
#$sqlbc.Batchsize = 1000
#$sqlbc.BulkCopyTimeout = 60
#$sqlbc.EnableStreaming=$true
# add all columns - you can add as few as you like.
for ($i = 0; $i -lt $rdr.FieldCount; $i++) {
$fname = $rdr.GetName($i)
Write-Host $fname -ForegroundColor green
[void]$sqlbc.ColumnMappings.Add($fname, $fname)
}
# write all of the data to the table
Try {
$sqlbc.WriteToServer($rdr)
} Catch {
Write-Host "$_" -Fore red -back white
} Finally {
$rdr.Close()
}
} Catch {
Write-Host "$_" -ForegroundColor red
}
When I run the program which needs to use the OLE DB Provider, it gives the error: "The Microsoft.ACE.OLEDB.12.0 Provider is not registered on the local machine. Can someone tell me why it can not find the provider when it is already there.
I tried dowloading Microsoft Database Access Engine 2017 and Microsoft Database Access Engine 2010 Redistributible and still have the same error. I also restart my computer and try run as administrator.... No thing worked for me.
Could anyone help me with this? Thanks.
The OLEDB provider are 32-bit and 64-bit aware.
If only 32-bit provider is installed (when installed Office is 32-bit),
The script must be run using powershell (x86).
To do that, run this command:
& "$Env:WINDIR\SysWOW64\WindowsPowerShell\v1.0\powershell.exe" -File <script_file_path>
To list installed OLEDB, see List all Ole DB Providers in Powershell.
The output may be different when run in Powershell (x64) and Powershell (x86).
function Get-OledbRegistered
{
[CmdletBinding()]
[OutputType([System.Collections.Generic.List[PSObject]])]
param ()
Process
{
$list = New-Object ([System.Collections.Generic.List[PSObject]])
foreach ($provider in [System.Data.OleDb.OleDbEnumerator]::GetRootEnumerator())
{
$v = New-Object PSObject
for ($i = 0; $i -lt $provider.FieldCount; $i++)
{
Add-Member -in $v NoteProperty $provider.GetName($i) $provider.GetValue($i)
}
$list.Add($v)
}
return $list
}
}
Get-OledbRegistered
I've been working on a little project in Powershell.
My task was to create a script that will collect all files from mail attachments, merge all .pdf files into one and send the generated file to my email.
The script works completely fine in Powershell ISE, but when I try to run it from task scheduler, the merged .pdf file is corrupted without any data in it.
Keep in mind I am new to this stuff.
This is my main code that does all the heavy work:
function getAttachments
{
#########################################################
##-----------------------------------------------------##
## GET ATTACHMENTS ##
##-----------------------------------------------------##
#########################################################
##PATH TO CREDENTIAL
$credpath = "C:\Users\" + $env:UserName + "\Documents\myCred_${env:USERNAME}_${env:COMPUTERNAME}.xml"
#test variable
$test = Test-Path $credpath
##TEST IF CREDENTIAL EXISTS
if(!$test){
## USER PROMPT PSW CREDENTIAL ##
$cred = Get-Credential
#save credential in documents
$cred | Export-CliXml -Path $credpath
}else{
##READ USER CREDENTIAL FROM FILE
$cred = Import-CliXml -Path $credpath
}
##url and date variables
$url = "https://outlook.office365.com/api/v1.0/me/messages"
$d = [DateTime]::Today.AddDays(-1)
$global:date = $d.ToString("yyyy-MM-dd")
## Get all messages that have attachments where received date is greater than $date
$messageQuery = "" + $url + "?`$select=Id&`$filter=HasAttachments eq true and DateTimeReceived ge " + $date
$messages = Invoke-RestMethod $messageQuery -Credential $cred
## Loop through each results
foreach ($message in $messages.value)
{
# get attachments and save to file system
$query = $url + "/" + $message.Id + "/attachments"
$attachments = Invoke-RestMethod $query -Credential $cred
# in case of multiple attachments in email
foreach ($attachment in $attachments.value)
{
Write-Host “Found File :- ” $attachment.Name
$path = "c:\Attachments\" + $attachment.Name
$Content = [System.Convert]::FromBase64String($attachment.ContentBytes)
Set-Content -Path $path -Value $Content -Encoding Byte
}
}
}
function sendAttachments
{
#############################################################
##---------------------------------------------------------##
## SEND ATTACHMENTS AND DELETE FILES ##
##---------------------------------------------------------##
#############################################################
#Connection Details
#PATH TO CREDENTIAL
$credpath = "C:\Users\" + $env:UserName + "\Documents\myCred_${env:USERNAME}_${env:COMPUTERNAME}.xml"
$cred = Import-CliXml -Path $credpath
$smtpServer = “ smtp.office365.com”
$msg = new-object Net.Mail.MailMessage
#Change port number for SSL to 587
$smtp = New-Object Net.Mail.SmtpClient($SmtpServer, 25)
#Uncomment Next line for SSL
$smtp.EnableSsl = $true
$smtp.Credentials = $cred
$msg.IsBodyHtml = $true
#From Address
$msg.From = $cred.UserName
#To Address, Copy the below line for multiple recipients
$msg.To.Add(“email#gmail.com”)
#Message Body
$msg.Body=”<h2>Alle attachments samen bevinden zich in de bijlage van did email</h2> <br/><br/>”
#Message Subject
$msg.Subject = “no-reply: Email met alle attachments”
#your file location
$files=Get-ChildItem “C:\Attachments\”
#attach the right file
$file = $global:pname
Write-Host “Attaching File :- ” $file
$attachment = New-Object System.Net.Mail.Attachment –ArgumentList C:\Attachments\$file
$msg.Attachments.Add($attachment)
#send email
$smtp.Send($msg)
$attachment.Dispose();
$msg.Dispose();
#delete the files from the folder
Get-ChildItem -Path C:\Attachments -Include * -File -Recurse | foreach { $_.Delete()}
}
function mergePDF
{
#############################################################
##---------------------------------------------------------##
## MERGE ALL PDF FILES ##
##---------------------------------------------------------##
#############################################################
$workingDirectory = "C:\Attachments"
$itspath = $PSScriptRoot
$global:pname = $global:date + "_pdfAttachments.pdf"
$pdfs = ls $workingDirectory -recurse | where {-not $_.PSIsContainer -and $_.Extension -imatch "^\.pdf$"};
[void] [System.Reflection.Assembly]::LoadFrom([System.IO.Path]::Combine($itspath, 'itextsharp.dll'));
$output = [System.IO.Path]::Combine($workingDirectory, $pname);
$fileStream = New-Object System.IO.FileStream($output, [System.IO.FileMode]::OpenOrCreate);
$document = New-Object iTextSharp.text.Document;
$pdfCopy = New-Object iTextSharp.text.pdf.PdfCopy($document, $fileStream);
$document.Open();
foreach ($pdf in $pdfs) {
$reader = New-Object iTextSharp.text.pdf.PdfReader($pdf.FullName);
[iTextSharp.text.pdf.PdfReader]::unethicalreading = $true
$pdfCopy.AddDocument($reader);
$reader.Dispose();
}
$document.Close()
$pdfCopy.Dispose();
$document.Dispose();
$fileStream.Dispose();
}
getAttachments
Start-Sleep -s 10
mergePDF
Start-Sleep -s 10
sendAttachments
In this piece of code that I run in another script file, I create a new task:
#############################################################
##---------------------------------------------------------##
## SCHEDULE SCRIPTS IN WINDOWS TASKS ##
##---------------------------------------------------------##
#############################################################
##PATH TO CREDENTIAL
$credpath = "C:\Users\" + $env:UserName + "\Documents\myCred_${env:USERNAME}_${env:COMPUTERNAME}.xml"
#test variable
$test = Test-Path $credpath
##TEST IF CREDENTIAL EXISTS
if(!$test){
## USER PROMPT PSW CREDENTIAL ##
$cred = Get-Credential
#save credential in documents
$cred | Export-CliXml -Path $credpath
}
$taskName = "ManageEmailAttachments"
$taskExists = Get-ScheduledTask | Where-Object {$_.TaskName -like $taskName }
if($taskExists)
{
Get-ScheduledJob ManageEmailAttachments
Unregister-ScheduledJob ManageEmailAttachments
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("Task successfully deleted, run the script again to schedule the task",0,"Done",0x0)
}
else
{
$tt = Get-Date
$tt = $tt.AddMinutes(1)
$testtime = $tt.ToString("HH:mm:ss")
#set trigger
$trigger = New-JobTrigger -Daily -At "1:00"
$testtrigger = New-JobTrigger -Daily -At $testtime
#path to the scripts
$scriptPath = $PSScriptRoot + "\wps_manage_pdf_attachments.ps1"
#options(optional)
$option = New-ScheduledJobOption -WakeToRun: $true
#create a new task
Register-ScheduledJob -Name ManageEmailAttachments -FilePath $scriptPath -Trigger $testtrigger -ScheduledJobOption $option
}
The script when run in Powershell works great, it gets all the attachments from mailbox, merges them into 1 .pdf file and sends them to the requested email address. But when scheduled in windows task scheduler it does the first step fine, but when merged, the .pdf file is corrupted without any content.
I couldn't figure out how to make it work so I posted a question on the forum.
Hope you guys find a way to figure it out.
Thanks in advance
Use below function to get script root directory.
Function Get-ScriptDirectory
{
$Invocation = (Get-Variable MyInvocation -scope 1).Value
Split-path $Invocation.MyCommand.Path
}
$scriptPath=Join-Path(Get-ScriptDirectory) 'wps_manage_pdf_attachments.ps1'
Apparently the problem nested itself in the main code. I used:
Try{...}
Catch{$_ | Out-File C:\errors.txt}
In mergePDF function to find out what the error was. Seems like the path to my ITextSharp.dll was incorrect. $PSScriptRoot that I used showed "C:\windows\windows32" instead of where the script actually is.
So what I did instead was add a line in my batch file to copy the itextsharp.dll to %Temp%:
xcopy Scripts\itextsharp.dll %Temp% /D >NUL 2>NUL
and then read the file from there with:
$itsPath = [System.IO.Path]::GetTempPath()
And everything works as it should be. I know this isn't the best way to do it but I had this batch file before to make the script run by just dubbleclicking it.
So adding a little line won't hurt.
I hope this helps anyone with the same problem.