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)
Related
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.
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").
Im trying to build a way to create a folder structure in windows automatically absed on a job number and how many parts they will need. im able to get the code functioning to the point where i make the main folder, the sub folder and the sub folder in the folders with a part in it. the thing im looking to do however is transfer a different part into each folder based on priorities
There are max 7 priorities and that needs to be divided by how many parts so example would be there are 4 parts with 4 priorities.. (in this sample code it creates the sales folder, then puts a folder underneath it called conveyors then puts 4 folders in the conveyors folder with a number ) id like that to put four different parts in four different folders based on that how many priorities)
tried diving priorities but that wont work as i cant understand how to store an array to do what im asking
powershell
$salesorder = read-host -prompt 'What is the customer name and salesorder number? (ex.. turnkey - 3335)'
$jobnumber = read-host -prompt 'what is the Plant folder plus job number? (ex... 930-12345)'
$foldername = $jobnumber + " - " + $salesorder
#$conveyornumber = read-host -prompt "what is the number for conveyors? " + " - "
$priority = read-host -prompt "how many priorities are there?"
##************************* setting variables for second level basic Folder Structure *********************************
$partpath = '\\wal-file\public\sullivan\sully_temp_part.ipt'
$layout = 'D0100 - Layout'
$footprint = 'D0101 - Footprint'
$equipment = 'D01xx - Equipment'
$Guarding = 'D85xx - Guarding'
$conveyor = 'D60xx - Conveyors'
$platform = 'D90xx - Platforms'
#*************************** creating new variables based on folder name stylings *************************************
$workdir = new-item -path "C:\vault_workspace\Temp_vault\wendt\" -name $foldername -itemtype 'directory' -force
$layoutdir = new-item -path $workdir -name $layout -itemtype 'directory'
$layoutfilename = $layoutdir -join '.ipt'
#*************************** setting work directory input **************************************************************
new-item -path $layoutdir -name "$salesorder.ipt" -itemtype "file"
$footprintdir = new-item -path $workdir -name $footprint -itemtype 'directory'
$conveyordir = new-item -path $workdir -name $conveyor -itemtype 'directory'
#looping statement to create multiple folders
$conveyorinput = read-host -prompt "how many conveyors need to be made?"
for ($i = 1; $i -le $conveyorinput; $i++){"{0:D2}" -f $number} { [system.io.directory]::CreateDirectory("$conveyordir\D51$I")}
start-sleep -seconds 5
#creating multiple files
$conveyorarray = Get-ChildItem $conveyordir | Where-Object {$_.PSChildname} | Foreach-Object {$_.Name}
foreach ($path in $conveyorarray) {copy-item -path $partpath -destination "$conveyordir\$path\$jobnumber-4-$path-DUmmy-A0.ipt "}
i tried a few things all with mixed results no here close to what im looking to d. i tried goodling it but i couldnt figure out a way to implement anything close to what im asking some form of If statement would probably do it, but where would i put it and how would it work?
Thanks for any help
This is just a suggestion, can you look at adding functions so your code is readable. I can't see what you want. Can you also pepper it with output if you need to see what is going on Write-Host. I don't know what a sully sample is or how it is related to this so my guess is it's a folder or an ipt file? I can't read the code code-readability as it doesn't convey what you intend to to as far as I can tell beyond creating directories? If you can leave out the 'sully sample' language and use widget I think we could understand it better. Such as I need 4 Widget files for 4 people to look at?
# powershell
$salesorder = read-host -prompt 'What is the customer name and salesorder number? (ex.. turnkey - 3335)'
$jobnumber = read-host -prompt 'what is the Plant folder plus job number? (ex... 930-12345)'
$foldername = $jobnumber + " - " + $salesorder
#$conveyornumber = read-host -prompt "what is the number for conveyors? " + " - "
$priority = read-host -prompt "how many priorities are there?"
##************************* setting variables for second level basic Folder Structure *********************************
# Dunno what this file is or how it got here?
$partpath = '\\wal-file\public\sullivan\sully_temp_part.ipt'
$layout = 'D0100 - Layout'
$footprint = 'D0101 - Footprint'
$equipment = 'D01xx - Equipment' #Are these meant to be numbers or x character?
$Guarding = 'D85xx - Guarding'
$conveyor = 'D60xx - Conveyors'
$platform = 'D90xx - Platforms'
#*************************** creating new variables based on folder name stylings *************************************
$folderArray = #() # of things you want to keep track of
function CreateNewFolder() {
param(
$path = "C:\vault_workspace\Temp_vault\wendt\",
$name = $foldername,
[switch] $force
)
$newDirectory = new-item -path $path -name $name -itemtype 'directory' -force:$force
Write-Host "Adding $name to FolderArray"
$folderArray.Add($newDirectory)
return $newDirectory
}
$workdir = CreateNewFolder -path "C:\vault_workspace\Temp_vault\wendt\" -name $foldername -force
#$workdir = new-item -path "C:\vault_workspace\Temp_vault\wendt\" -name $foldername -itemtype 'directory' -force
$layoutdir = CreateNewFolder -path $workdir -name $layout
#$layoutdir = new-item -path $workdir -name $layout -itemtype 'directory'
$layoutfilename = $layoutdir -join '.ipt' # Why are we joining the directory to ipt?
#*************************** setting work directory input **************************************************************
new-item -path $layoutdir -name "$salesorder.ipt" -itemtype "file"
#$footprintdir = new-item -path $workdir -name $footprint -itemtype 'directory'
$footprintdir = CreateNewFolder -path $workdir -name $footprint
$conveyordir = new-item -path $workdir -name $conveyor -itemtype 'directory'
#looping statement to create multiple folders
$conveyorinput = read-host -prompt "how many conveyors need to be made?"
for ($i = 1; $i -le $conveyorinput; $i++){
# This just gets printed out?
"{0:D2}" -f $number
}
{
[system.io.directory]::CreateDirectory("$conveyordir\D51$I")
}
start-sleep -seconds 5
#creating multiple files
$conveyorarray = Get-ChildItem $conveyordir | Where-Object {
$_.PSChildname
} | Foreach-Object {
#{
Name = $_.Name
FullName = $_.FullName
}
}
foreach ($path in $conveyorarray) {
$name = $_.Name
$fullName = $_.Name
$destination = '{0}\{1}\{2}-4-{3}-Dummy-A0.ipt' -f $conveyordir, $name, $jobnumber, $path
copy-item -path $fullName -destination $destination # "$conveyordir\$path\$jobnumber-4-$path-DUmmy-A0.ipt "
}
so i actually changed the suyntax around completely but i was able to do the following
$salesorder = read-host -prompt 'What is the customer name and salesorder number? (ex.. turnkey - 3335)'
$jobnumber = read-host -prompt 'what is the Plant folder plus job number? (ex... 930-12345)'
$topleveldir = new-item -path "C:\vault_workspace\Temp_vault\wendt\" -name "M$jobnumber - $salesorder" -ItemType 'directory'
$subfolders = "D0100 - Layout", "D0101 - Footprint", "D01xx - Equipment","D85xx - Guarding", "D60xx - Conveyors", "D90xx - Platforms", "D09XX - Chutes"
foreach($subfolder in $subfolders){new-item -path "$topleveldir" -name $subfolder -type directory }
#$partpath = '\\wal-file\public\sullivan\sully_temp_part.ipt'
#p1
$p1conveyorinput = read-host -prompt "how many p1 conveyors need to be made?"
for ($i = 1; $i -le $p1conveyorinput; $i++) {
$p1c = "{0:D2}" -f $i
[system.io.directory]::CreateDirectory("$topleveldir\D60xx - Conveyors\D61$p1c-p1")
copy-item -path "\\wal-file\public\sullivan\sully_temp_part.ipt" -destination "$topleveldir\D60xx - Conveyors\D61$p1c-p1\D61$p1c-p1-dummy.ipt" -force
}
start-sleep -seconds 1
the only issue i run into is how to loop back into that last statement
#p1
$p1conveyorinput = read-host -prompt "how many p1 conveyors need to be made?"
for ($i = 1; $i -le $p1conveyorinput; $i++) {
$p1c = "{0:D2}" -f $i
[system.io.directory]::CreateDirectory("$topleveldir\D60xx - Conveyors\D61$p1c-p1")
copy-item -path "\\wal-file\public\sullivan\sully_temp_part.ipt" -destination "$topleveldir\D60xx - Conveyors\D61$p1c-p1\D61$p1c-p1-dummy.ipt" -force
}
start-sleep -seconds 1
for as many priorities there are without copying and changing the variables (which im going to do for now because it functions)
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.
I am working on a disk space script for our clients in my off time. I just tested it using the ISE, and it looks like it was working until I checked the transcript.
There are sections during the first removal cycle around line 32 where it is removing files in C:\Windows\System32\, which of course I didn't want it to. I am sure I did something wrong, but I have checked for typos, and I do not understand how it can get %system32% from a users directory.
If (([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
{
$Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + ' (Elevated)'
$Host.UI.RawUI.BackgroundColor = 'DarkBlue'
Clear-Host
}
Else
{
$newProcess = New-Object Diagnostics.ProcessStartInfo 'PowerShell'
$newProcess.Arguments = "& '" + $script:MyInvocation.MyCommand.Path + "'"
$newProcess.Verb = 'runas'
[Diagnostics.Process]::Start($newProcess) | Out-Null
exit
}
If ((Test-Path "C:\DiskSpaceCleanupLog\") -eq $False)
{
New-Item -ItemType Directory -Path "C:\DiskSpaceCleanupLog\"
}
$Date = [string]::Format( "{0:dd-MM-yyyy}", [datetime]::Now.Date )
$LogName = "C:\DiskSpaceCleanupLog\" + $Date + "Log.txt"
Start-Transcript $LogName
$Path = #()
$Array = #(Get-ChildItem C:\Users | Select-Object Name)
Read-Host -Verbose "Removing User Account temp files..."
Foreach ($Name IN $Array)
{
$Path = ("C:\Users\" + $Name.Name + "\AppData\Local\Temp\")
}
Foreach ($Path IN $Array)
{
Get-ChildItem | Remove-Item -Recurse -WhatIf
}
Remove-Variable Path
Read-Host -Verbose "Removing User Account crash dumps..."
Foreach ($Name IN $Array)
{
$Path = ("C:\Users\" + $Name.Name + "\AppData\Local\CrashDumps\")
}
Foreach ($Path IN $Array)
{
Get-ChildItem | Remove-Item -Recurse -WhatIf
}
Remove-Variable Path
Read-Host -Verbose "Removing User Account reporting files..."
Foreach ($Name IN $Array)
{
$Path = ("C:\Users\" + $Name.Name + "\AppData\Local\Microsoft\Windows\WER\ReportArchive\")
}
Foreach ($Temp IN $Path)
{
Get-ChildItem | Remove-Item -Recurse -WhatIf
}
Remove-Variable Path
Read-Host -Verbose "Removing User Account temp files from Internet Explorer..."
Foreach ($Name IN $Array)
{
$Path = ("C:\Users\" + $Name.Name + "\AppData\Local\Microsoft\Windows\Temporary Internet Files\")
}
Foreach ($Temp IN $Path)
{
Get-ChildItem | Remove-Item -Recurse -WhatIf
}
Read-Host -Verbose "Removing Recycle Bin files..."
Remove-Item -LiteralPath 'C:\$Recycle.Bin\' -Recurse -WhatIf
Read-Host -Verbose "Removing global crash dumps..."
Remove-Item "C:\ProgramData\Microsoft\Windows\WER\ReportQueue" -Recurse -WhatIf
Remove-Item "C:\ProgramData\Microsoft\Windows\WER\ReportArchive" -Recurse -WhatIf
Read-Host -Verbose "Removing Windows Update cached files..."
Stop-Service -DisplayName 'Windows Update'
Remove-Item "C:\Windows\SoftwareDistribution\Download\*" -Recurse -WhatIf
Start-Service -DisplayName 'Windows Update'
Remove-Variable Array, Path
Read-Host -Verbose "Cleaning base image of update cache..."
DISM.exe /Online /Cleanup-Image /SPSuperseded
Read-Host -Verbose "Running Windows Clean Manager..."
$OSVersion = Get-WMIObject -Class Win32_OperatingSystem | Format-Table Version
If ($OSVersion -le 6.1)
{
cleanmgr.exe /verylowdisk
}
Read-Host -Verbose "Removal is complete. Sending logs..."
Stop-Transcript
$SecurePassword = ConvertTo-SecureString "InsertPasswordHere" -AsPlainText -Force
$emailcredential = New-Object System.Management.Automation.PSCredential ("email#domain.com", $SecurePassword)
Send-MailMessage -To "Name Here <email#domain.com>" -From "Name Here <email#domain.com>" -Subject ("Disk Space Cleanup Log - " + $Date) -Body "Attached is the log from the script." -Attachments $LogName -SmtpServer "smtp.office365.com" -Credential $emailcredential -UseSSL -Port "587" -DeliveryNotificationOption OnFailure
Line 32 is Get-ChildItem | Remove-Item -Recurse -WhatIf
The are several things that should be adjusted in your code but the issue that is befalling you now is that you have not specified a -Path. Therefore Get-ChildItem will be returning items from the working directory!
Get-ChildItem | Remove-Item -Recurse -WhatIf
Should be instead
Get-ChildItem $path | Remove-Item -Recurse -WhatIf
Like I said though there are several potential pitfalls and areas of improvement there to be addressed. You use the same loop 5 times. A couple are exactly the same.
I believe the issue is on line 23, where the code is not populating the array with full pathnames. See Get full path of the files in PowerShell for some advice on how to get the full pathnames instead.