We help IT Professionals succeed at work.

Check out our new AWS podcast with Certified Expert, Phil Phillips! Listen to "How to Execute a Seamless AWS Migration" on EE or on your favorite podcast platform. Listen Now

x
Private

Help with PowerShell reading from a CSV file

High Priority
76 Views
Last Modified: 2020-06-25
Hello Experts,

Can someone please help with the following, Is there a way to to have the following powershell run against the a CSV and use the CSV-RECEIPIENT, CSV-SENDER and CSV-SUBJECT from the a CSV file that will be provided.

The goal is to be able to run a script that will check the CSV and process the command for every entry in the CSV file.  


Search-Mailbox -Identity CSV-RECEIPIENT -SearchQuery "From:CSV-SENDER AND Subject:'CSV-SUBJECT'" -TargetMailbox Recovery -TargetFolder Deleted -LogLevel Full -DeleteContent

For the time being we have to manually enter the values, something like this:

Search-Mailbox -Identity dmccall@mydomain.com -SearchQuery "From:tranmax@mail.com AND Subject:'Report'" -TargetMailbox Recovery -TargetFolder Deleted -LogLevel Full -DeleteContent


CSV file example:


Date	Sender	Recipient	Recipient Domain	Sender IP	Filter Action	Subject
2020-05-21T11:10:58-04:00	karina.santiago@pegasie.com	jroyal@mydomain.com	mydomain.com	173.46.152.178	ACCEPT	Smart Testing: What if you knew exactly what to test?
2020-05-21T11:10:49-04:00	terry.england@pegasie.com	jpowers@mydomain.com	mydomain.com	173.46.152.177	ACCEPT	Smart Testing: What if you knew exactly what to test?
2020-05-20T11:34:57-04:00	karina.santiago@pegasie.com	enyman@mydomain.com	mydomain.com	173.46.152.178	ACCEPT	Smart Testing: What if you knew exactly what to test?
2020-05-20T11:34:53-04:00	terry.england@pegasie.com	dstamidis@mydomain.com	mydomain.com	173.46.152.177	ACCEPT	Smart Testing: What if you knew exactly what to test?

Open in new window


Thank you!
Comment
Watch Question

CERTIFIED EXPERT
Most Valuable Expert 2019
Most Valuable Expert 2018

Commented:
This should do it:
Import-Csv -Path 'C:\Temp\Whatever.csv' | ForEach-Object {
	Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox Recovery -TargetFolder Deleted -LogLevel Full -DeleteContent
}

Open in new window

David Johnson, CDSimple Geek from the '70s
CERTIFIED EXPERT
Distinguished Expert 2019

Commented:
#1 it isn't a CSV  == comma separated values


This is a CSV
Date,Sender,Recipient,"Recipient Domain","Sender IP","Filter Action",Subject
2020-05-21T11:10:58-04:00,karina.santiago@pegasie.com,jroyal@mydomain.com,mydomain.com,173.46.152.178,ACCEPT,"Smart Testing: What if you knew exactly what to test?"
2020-05-21T11:10:49-04:00,terry.england@pegasie.com,jpowers@mydomain.com,mydomain.com,173.46.152.177,ACCEPT,"Smart Testing: What if you knew exactly what to test?"
2020-05-20T11:34:57-04:00,karina.santiago@pegasie.com,enyman@mydomain.com,mydomain.com,173.46.152.178,ACCEPT,"Smart Testing: What if you knew exactly what to test?"
2020-05-20T11:34:53-04:00,terry.england@pegasie.com,dstamidis@mydomain.com,mydomain.com,173.46.152.177,ACCEPT,"Smart Testing: What if you knew exactly what to test?"

Open in new window

CERTIFIED EXPERT
Most Valuable Expert 2019
Most Valuable Expert 2018

Commented:
Depends on how the output in the code block was generated. If it was copied and pasted from Excel, it will be exported as tab delimited text, which is a cs v file as well. In this case, the underlying file can still be comma separated.
Or it could be an extract of a real csv, only with tab as delimiter, in which case Import-Csv needs to be told to use it:
Import-Csv -Path 'C:\Temp\Whatever.csv' -Delimiter "`t" | ForEach-Object {
	Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox Recovery -TargetFolder Deleted -LogLevel Full -DeleteContent
}

Open in new window

Author

Commented:
Thanks oBdA!

I've attached a screen cap of the way the CSV that we are provided with looks like. 

Author

Commented:
I've modified your script a bit with the following:

I am using LogOnly first which should provide a visual of whats going to be deleted first. Would it be possible to get the output of the LogOnly and then display some message saying something...if you want to proceed with the purge type "yes" and enter. Then that will run the same script but we will change -LogLevel Full -DeleteContent

Import-Csv -Path 'C:\Temp\search-20200526-32025-1e1ot8g.csv' -Delimiter "`t" | ForEach-Object {
   Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox ExportedMessages -TargetFolder Ticket:429759 -LogOnly -LogLevel Full 
}
To delete after the confirming with a "YES"

Import-Csv -Path 'C:\Temp\search-20200526-32025-1e1ot8g.csv' -Delimiter "`t" | ForEach-Object {
   Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox ExportedMessages -TargetFolder Ticket:429759 -LogLevel Full -DeleteContent 
}
Thank you! 

Author

Commented:
oBdA,

I ran the following:

Import-Csv -Path 'C:\Temp\search-20200526-32025-1e1ot8g.csv' -Delimiter "`t" | ForEach-Object {
   Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox ExportedMessages -TargetFolder Ticket:429759 -LogOnly -LogLevel Full }
but I am getting the following error

Cannot bind argument to parameter 'Identity' because it is null.
    + CategoryInfo          : InvalidData: (:) [Search-Mailbox], ParameterBindingValidationException

I might be missing something...
CERTIFIED EXPERT
Most Valuable Expert 2019
Most Valuable Expert 2018

Commented:
Open the csv file in an Editor, not in Excel, and check what's used as delimiter.
Then set the $delimiter variable accordingly:
$csvFile = 'C:\Temp\search-20200526-32025-1e1ot8g.csv'
$delimiter = ','

Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
   Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox ExportedMessages -TargetFolder Ticket:429759 -LogOnly -LogLevel Full
} | Out-GridView -Wait 

$choices = @(
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Purge', 'Proceed with the purge'
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Cancel', 'Leave without changes'
)
$answer = $host.UI.PromptForChoice('Purge Content', '', $choices, ($choices.Count - 1))

If ($answer -eq $choices.Count - 1) {
	Write-Host 'Goodbye'
} Else {
	Write-Host 'Deleting ...'
	Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
	   Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox ExportedMessages -TargetFolder Ticket:429759 -LogLevel Full -DeleteContent 
	}
}

Open in new window


Edit: Fixed a superfluous "}" that smuggled itself into the script.
CERTIFIED EXPERT
Most Valuable Expert 2019
Most Valuable Expert 2018

Commented:
Fixed an issue in the script above ...

Author

Commented:
Your are great thanks!

I am trying to figure out an error with the first part but it's not the script, looks like it's related to the cmdlet itself.

WARNING: The Search-Mailbox cmdlet returns up to 10000 results per mailbox if a search query is specified. To return
more than 10000 results, use the New-MailboxSearch cmdlet or the In-Place eDiscovery & Hold console in the Exchange
Administration Center.
The property keyword isn't supported.
    + CategoryInfo          : InvalidArgument: (:) [], ParserException

Would it be possible to send an email with the output of the purge? some sort of log with the output that will be send to an email address to indicate that the process has completed and the result of it?

Thanks again for your help!  

Author

Commented:
Looks like the error I am getting can only by bypassed by doing some sort of loop do you think that this is something that can be added to the script to bypass the current limitation?

https://www.exchangeitup.net/2017/01/exchange-search-mailbox-delete-more.html 



I am stuck right now :( thanks again!
CERTIFIED EXPERT
Most Valuable Expert 2019
Most Valuable Expert 2018

Commented:
Untested.
The warning for the first call of Search-Mailbox is still in, so that you'll know results ren't complete. To suppress them, add  "-WarningAction SilentlyContinue" at the end of the line.
$csvFile = 'C:\Temp\search-20200526-32025-1e1ot8g.csv'
$delimiter = ','
$logFile = 'C:\Temp\MailboxPurge.log'
$mailArgs = @{
	From = 'from@domain.com'
	To = 'to@domain.com'
	Subject = 'Mailbox purge'
	SmtpServer = 'smpt.domain.com'
	Attachments = $logFile
}

Start-Transcript -Path $LogFile
Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
	Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox ExportedMessages -TargetFolder Ticket:429759 -LogOnly -LogLevel Full
} | Out-GridView -Wait 

$choices = @(
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Purge', 'Proceed with the purge'
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Cancel', 'Leave without changes'
)
$answer = $host.UI.PromptForChoice('Purge Content', '', $choices, ($choices.Count - 1))

If ($answer -eq $choices.Count - 1) {
	Write-Host 'Goodbye'
} Else {
	Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
		Write-Host "Deleting mails for $($_.Recipient) ..."
		Do {
			$result = Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox ExportedMessages -TargetFolder Ticket:429759 -LogLevel Full -DeleteContent -Force -WarningAction SilentlyContinue
			Write-Host "    - Deleted $($result.ResultItemsCount) items"
		} Until ($result.ResultItemsCount -eq 0)
	}
}
Stop-Transcript
Send-MailMessage @mailArgs

Open in new window

Author

Commented:
It's amazing the way you get this done...

The first part (log only) works as expected but somehow looks like I am getting an error then when proceeding with the purge the command it's issued but then I get the following error:

Cannot bind argument to parameter 'Identity' because it is null.
    + CategoryInfo          : InvalidData: (:) [Search-Mailbox], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Search-Mailbox

I found a similar post but that was an empty string this is one says it is null but somehow runs something first. 

https://community.spiceworks.com/topic/2023293-cannot-bind-argument-to-parameter-identity-because-it-is-an-empty-string 

And I promise the last one! could the -TargetFolder  be made into a manual input? so they can type the ticket number manually and then the script will use it in the command?

-TargetMailbox ExportedMessages -TargetFolder Ticket:429759 -LogOnly -LogLevel Full -WarningAction SilentlyContinue

Thank you so much for helping!  
CERTIFIED EXPERT
Most Valuable Expert 2019
Most Valuable Expert 2018

Commented:
It's doing the exact same loop over the exact same csv twice, so if this error happens in the second loop. I don't see a way for it to not happen in the first loop as well.
So make sure there are no empty rows in the csv.
You should have some lines "Deleting mails for ..." before that, so check out the line in the csv after the last valid name.
$targetFolder = Read-Host "Please enter the target folder (ex: Ticket:429759)"
$csvFile = 'C:\Temp\search-20200526-32025-1e1ot8g.csv'
$delimiter = ','
$logFile = 'C:\Temp\MailboxPurge.log'
$mailArgs = @{
	From = 'from@domain.com'
	To = 'to@domain.com'
	Subject = 'Mailbox purge'
	SmtpServer = 'smpt.domain.com'
	Attachments = $logFile
}

Start-Transcript -Path $LogFile
Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
	Write-Host "Searching mails for '$($_.Recipient)' ..."
	Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox ExportedMessages -TargetFolder $targetFolder -LogOnly -LogLevel Full
} | Out-GridView -Wait 

$choices = @(
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Purge', 'Proceed with the purge'
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Cancel', 'Leave without changes'
)
$answer = $host.UI.PromptForChoice('Purge Content', '', $choices, ($choices.Count - 1))

If ($answer -eq $choices.Count - 1) {
	Write-Host 'Goodbye'
} Else {
	Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
		Write-Host "Deleting mails for '$($_.Recipient)' ..."
		Do {
			$result = Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox ExportedMessages -TargetFolder $targetFolder -LogLevel Full -DeleteContent -Force -WarningAction SilentlyContinue
			Write-Host "    - Deleted $($result.ResultItemsCount) items"
		} Until ($result.ResultItemsCount -eq 0)
	}
}
Stop-Transcript
Send-MailMessage @mailArgs

Open in new window

Author

Commented:
Hi oBdA,

Sorry for the delay providing an update. I have been testing extensively and I have found the following behavior.  The -LogOnly -LogLevel Full loop goes over the CSV and prints out (Out-GridView) with recipients that are valid and are part of the organization, there are some receipients that are part of the CSV that do not exist and they error out and are not printed out which if fine.

The issue happens with the -LogLevel Full -DeleteContent -Force loop when the script hits one of the recipients that do not exist then enters in a endless loop and does not move to the next one.

The screenshot below shows a non existent recepient that part of the CSV - cfogart@mydomain.com 

 
When the -LogLevel Full -DeleteContent -Force gets to cfogart@mydomain.com the script goes into an endless loop with the same recipient and does not move to the next one. Keeps on looping the same one over and over.  



I did my best trying to explain the issue hopefully you know what's going on I tried a few things but nothing appears to work.

Thank you again for your help! 
CERTIFIED EXPERT
Most Valuable Expert 2019
Most Valuable Expert 2018

Commented:
This should fix it:
$targetFolder = Read-Host "Please enter the target folder (ex: Ticket:429759)"
$csvFile = 'C:\Temp\search-20200526-32025-1e1ot8g.csv'
$delimiter = ','
$logFile = 'C:\Temp\MailboxPurge.log'
$mailArgs = @{
	From = 'from@domain.com'
	To = 'to@domain.com'
	Subject = 'Mailbox purge'
	SmtpServer = 'smpt.domain.com'
	Attachments = $logFile
}

Start-Transcript -Path $LogFile
Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
	Write-Host "Searching mails for '$($_.Recipient)' ..."
	Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox ExportedMessages -TargetFolder $targetFolder -LogOnly -LogLevel Full
} | Out-GridView -Wait 

$choices = @(
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Purge', 'Proceed with the purge'
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Cancel', 'Leave without changes'
)
$answer = $host.UI.PromptForChoice('Purge Content', '', $choices, ($choices.Count - 1))

If ($answer -eq $choices.Count - 1) {
	Write-Host 'Goodbye'
} Else {
	Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
		Write-Host "Deleting mails for '$($_.Recipient)' ..."
		Try {
			Do {
				$result = Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:'$($_.Subject)'" -TargetMailbox ExportedMessages -TargetFolder $targetFolder -LogLevel Full -DeleteContent -Force -WarningAction SilentlyContinue -ErrorAction Stop
				Write-Host "    - Deleted $($result.ResultItemsCount) items"
			} Until (-not $result -or ($result.ResultItemsCount -eq 0))
		} Catch {
			$_ | Write-Error
		}
	}
}
Stop-Transcript
Send-MailMessage @mailArgs

Open in new window

Author

Commented:
Great! Looks like that might do it! I also found out during testing that the way I was doing the syntax won't work well when we are using AND conditions

This is not correct:

Search-Mailbox -Identity clin3@mdmercy.com -SearchQuery "From:Williams_Michael@rsccd.edu AND Subject:'RE: MIGRATION.'" -TargetMailbox ExportedMessages -TargetFolder Ticket:429759 -LogOnly -LogLevel Full

This is the correct:

Search-Mailbox -Identity clin3@mydomain.com -SearchQuery ‘From:”Williams_Michael@rsccd.edu” AND Subject:”RE: MIGRATION.”’ -TargetMailbox ExportedMessages -TargetFolder Ticket:429759 -LogOnly -LogLevel Full

Would it be possible to adjust the code to include the quotation that I have used with the correct example to solve the issue with the AND/Conditions  

Thank you so much!



CERTIFIED EXPERT
Most Valuable Expert 2019
Most Valuable Expert 2018

Commented:
I somewhat doubt that these characters are correct; have a really close look, the ones you posted are the curly ones, not the straight ones that are required both in PS and KQL. What did you use to create the sample command? You should use a proper editor (Notepad if nothing else is available, Notepad++ is better and lightweight, VS Code for the heavy lifting).
You posted:               ‘From:”Williams...ON.”’
What it should look like: 'From:"Williams...ON."'

Open in new window

This will now wrap the subject in double quotes:
$targetFolder = Read-Host "Please enter the target folder (ex: Ticket:429759)"
$csvFile = 'C:\Temp\search-20200526-32025-1e1ot8g.csv'
$delimiter = ','
$logFile = 'C:\Temp\MailboxPurge.log'
$mailArgs = @{
	From = 'from@domain.com'
	To = 'to@domain.com'
	Subject = 'Mailbox purge'
	SmtpServer = 'smpt.domain.com'
	Attachments = $logFile
}

Start-Transcript -Path $LogFile
Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
	Write-Host "Searching mails for '$($_.Recipient)' ..."
	Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:`"$($_.Subject)`"" -TargetMailbox ExportedMessages -TargetFolder $targetFolder -LogOnly -LogLevel Full
} | Out-GridView -Wait 

$choices = @(
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Purge', 'Proceed with the purge'
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Cancel', 'Leave without changes'
)
$answer = $host.UI.PromptForChoice('Purge Content', '', $choices, ($choices.Count - 1))

If ($answer -eq $choices.Count - 1) {
	Write-Host 'Goodbye'
} Else {
	Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
		Write-Host "Deleting mails for '$($_.Recipient)' ..."
		Try {
			Do {
				$result = Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:`"$($_.Subject)`"" -TargetMailbox ExportedMessages -TargetFolder $targetFolder -LogLevel Full -DeleteContent -Force -WarningAction SilentlyContinue -ErrorAction Stop
				Write-Host "    - Deleted $($result.ResultItemsCount) items"
			} Until (-not $result -or ($result.ResultItemsCount -eq 0))
		} Catch {
			$_ | Write-Error
		}
	}
}
Stop-Transcript
Send-MailMessage @mailArgs

Open in new window

Author

Commented:
Sounds good! I did some additional testing over the weekend and everything seems to be working. The one last thing that will be very useful is to be able to input the name of the CSV file the same way we do input the ticket #. Is that something that can be done?

Thank you so much! 

Author

Commented:
Oh also one more quick question.. in the deleting section why do we get a duplicated entry for deleted X items?

Deleting mails for 'msumner1@mydomain' ...
    - Deleted 1 items
    - Deleted 0 items

Thank you!
CERTIFIED EXPERT
Most Valuable Expert 2019
Most Valuable Expert 2018

Commented:
That's because it loops the "DeleteContent" until it can't find anything to delete anymore.
$csvFile = Read-Host "Please enter the path to the csv file"
$targetFolder = Read-Host "Please enter the target folder (ex: Ticket:429759)"
# $csvFile = 'C:\Temp\search-20200526-32025-1e1ot8g.csv'
$delimiter = ','
$logFile = 'C:\Temp\MailboxPurge.log'
$mailArgs = @{
	From = 'from@domain.com'
	To = 'to@domain.com'
	Subject = 'Mailbox purge'
	SmtpServer = 'smpt.domain.com'
	Attachments = $logFile
}

Start-Transcript -Path $LogFile
Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
	Write-Host "Searching mails for '$($_.Recipient)' ..."
	Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:`"$($_.Subject)`"" -TargetMailbox ExportedMessages -TargetFolder $targetFolder -LogOnly -LogLevel Full
} | Out-GridView -Wait 

$choices = @(
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Purge', 'Proceed with the purge'
	New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Cancel', 'Leave without changes'
)
$answer = $host.UI.PromptForChoice('Purge Content', '', $choices, ($choices.Count - 1))

If ($answer -eq $choices.Count - 1) {
	Write-Host 'Goodbye'
} Else {
	Import-Csv -Path $csvFile -Delimiter $delimiter | ForEach-Object {
		Write-Host "Deleting mails for '$($_.Recipient)' ..."
		Try {
			Do {
				$result = Search-Mailbox -Identity $_.Recipient -SearchQuery "From:$($_.Sender) AND Subject:`"$($_.Subject)`"" -TargetMailbox ExportedMessages -TargetFolder $targetFolder -LogLevel Full -DeleteContent -Force -WarningAction SilentlyContinue -ErrorAction Stop
				Write-Host "    - Deleted $($result.ResultItemsCount) items"
			} Until (-not $result -or ($result.ResultItemsCount -eq 0))
		} Catch {
			$_ | Write-Error
		}
	}
}
Stop-Transcript
Send-MailMessage @mailArgs

Open in new window

Author

Commented:
Perfect, that makes sense. I’ve tested and it’s working great so far! I just realized that the log is overwritten every time the script runs, not sure if it’s too difficult but it will be helpful if we could create the log using the ticket number that is typed (ticket number) at the beginning of the script, that will help us with the search later on if something needs to be checked. Regardless thank you so much for your help!
CERTIFIED EXPERT
Most Valuable Expert 2019
Most Valuable Expert 2018

Commented:
Just embed the target name into the log file name, replacing the colon:
$logFile = "C:\Temp\MailboxPurge_$($targetFolder.Replace(':', '_')).log"

Open in new window

Author

Commented:
That worked! Looks like when entering the $targetFolder for the ticket number they can enter anything so if the enter a $ or anything else the process will continue. Would it be possible to secure the field to only allow numbers so illegal characters can not be entered? 

Thank you! :) 
CERTIFIED EXPERT
Most Valuable Expert 2019
Most Valuable Expert 2018
Commented:
Unlock this solution with a free trial preview.
(No credit card required)
Get Preview

Author

Commented:
oBdA- Thank you so much for help!
Unlock the solution to this question.
Thanks for using Experts Exchange.

Please provide your email to receive a free trial preview!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

OR

Please enter a first name

Please enter a last name

8+ characters (letters, numbers, and a symbol)

By clicking, you agree to the Terms of Use and Privacy Policy.