0

I have a script that dedupes 1 file against another (this part of the script works as expected, thanks to previous help), however I cannot seem to set the global variables properly.

Each indidual function appears to work as expected, but when the script reaches the "Dedupe" function it fails and cannot find the files that have been selected.

To get around the issue, I have tried embedding the processes into the if statements to create 1 function instead of calling others, but the same problem occurs.

Here is the original script:

$Global:SelectedSendFile = $null
$Global:SelectedSuppressionFile = $null
$Global:SelectedSaveFile = $null

function Instruction ($Message = "Select your send and suppression / unsubscribe lists,`nthen enter a new name to save the deduped list.", $Title = " Instructions") { 

    Add-Type -AssemblyName System.Windows.Forms | Out-Null
    $MsgBox = [System.Windows.Forms.MessageBox] 

    $Decision = $MsgBox::Show($Message,$Title,"OkCancel", " Information")

    If ($Decision -eq "OK") {BrowseSend}
    If ($Decision -eq "Cancel") {exit}
}
#End Instruction

function BrowseSend($initialDirectory)
{   
    Add-Type -AssemblyName System.Windows.Forms | Out-Null
    $SendFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $SendFileDialog.initialDirectory = $initialDirectory
    $SendFileDialog.Title = 'Please Select Send List'
    $SendFileDialog.filter = 'CSV (*.csv)| *.csv'
    $SelectedSendFile =  $SendFileDialog.filename

        if($SendFileDialog.ShowDialog() -eq "OK")    {    
            Write-Host 
            ""
            " Selected Send List:"  
            $SendFileDialog.filename        
            BrowseSuppression
        } 
        else {exit}
}
#End BrowseSend

function BrowseSuppression($initialDirectory)
{
    Add-Type -AssemblyName System.Windows.Forms | Out-Null  
    $SuppressionFileDialog = New-Object System.Windows.Forms.OpenFileDialog
    $SuppressionFileDialog.initialDirectory = $initialDirectory
    $SuppressionFileDialog.Title = 'Please Select Suppression / Unsubscribe List'
    $SuppressionFileDialog.filter = 'CSV (*.csv)| *.csv'
    $SelectedSuppressionFile =  $SuppressionFileDialog.filename


        if($SuppressionFileDialog.ShowDialog() -eq "OK")    {    
            Write-Host " Selected Suppression List:"  
            $SuppressionFileDialog.filename
            SaveFile
        } 
        else {exit}
} 
#End Suppression

function SaveFile($initialDirectory)
{ 
    Add-Type -AssemblyName System.Windows.Forms | Out-Null
    $SaveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
    $SaveFileDialog.Title = 'Save deduped list as'
    $SaveFileDialog.initialDirectory = $initialDirectory
    $SaveFileDialog.filter = "CSV (*.csv)| *.csv"
    $SelectedSaveFile = $SaveFileDialog.filename

        if($SaveFileDialog.ShowDialog() -eq "OK")    {    
            Write-Host " Save File As:"  
            $SaveFileDialog.filename  
            Dedupe
        } 
        else {exit}
} 
#End SaveFile

function Dedupe
{   
    ""
    ""
    " Reading lists, please wait... (this may take several minutes depending on the size of the file)"

    $fileA = Import-csv $SendFileDialog.filename
    $fileB = Import-csv $SuppressionFileDialog.filename

    $deduped = Compare-Object -Ref $fileA -Diff $fileB -Property email -PassThru | 
      Where-Object Sideindicator -eq '<=' | 
        Select-Object * -ExcludeProperty Sideindicator

    $deduped 
    $deduped | Export-Csv $SaveFileDialog.filename -NoTypeInformation

    $Cleanup = Get-ChildItem . $SaveFileDialog.filename -rec
    foreach ($file in $Cleanup)
    {
        (Get-Content $file.PSPath) |
        Foreach-Object { $_ -replace , """" } "" |
        Set-Content $file.PSPath
    }
    checkfile
} 
#End Dedupe

function checkfile{
    if ( (get-childitem $SaveFileDialog.filename).length -eq 0 )
    {Error}
    else
    {Complete}
}
#End checkfile

function Error ($Message = "Process has not been completed", $Title = " Error") { 

    Add-Type -AssemblyName System.Windows.Forms | Out-Null
    $MsgBox = [System.Windows.Forms.MessageBox] 

    $Decision = $MsgBox::Show($Message,$Title,"RetryCancel", "Error")

    If ($Decision -eq "Retry") {Instruction}
    If ($Decision -eq "Cancel") {exit}
}
#End Error

function Complete ($Message = "Export of the deduped list has been completed.", $Title = " Complete") { 

    Add-Type -AssemblyName System.Windows.Forms | Out-Null
    $MsgBox = [System.Windows.Forms.MessageBox] 

    $Decision = $MsgBox::Show($Message,$Title,"OK", " Information")

    If ($Decision -eq "OK") {exit}
}
#End Complete

Instruction

I think it's almost there, but I'm obviously missing something, any help would be appreciated.

EDIT: These are the errors I am getting:

Import-Csv : Cannot validate argument on parameter 'Path'. The argument is null or empty. Provide an argument that is not null or empty, and then 
try the command again.
At \\Mbp-nt01\dma\Digitial Marketing\___Shared folder for Email Team\_Fun_Template_2018\_remove dup - TEST\TEST2.ps1:98 char:22
+     $fileB = Import-csv $SupressionFileDialog.filename
+                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Import-Csv], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.PowerShell.Commands.ImportCsvCommand

Compare-Object : Cannot bind argument to parameter 'DifferenceObject' because it is null.
At \\Mbp-nt01\dma\Digitial Marketing\___Shared folder for Email Team\_Fun_Template_2018\_remove dup - TEST\TEST2.ps1:100 char:46
+     $deduped = Compare-Object -Ref $fileA -Diff $fileB -Property emai ...
+                                                 ~~~~~~
    + CategoryInfo          : InvalidData: (:) [Compare-Object], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CompareObjectCommand

Export-Csv : Cannot bind argument to parameter 'InputObject' because it is null.
At \\Mbp-nt01\dma\Digitial Marketing\___Shared folder for Email Team\_Fun_Template_2018\_remove dup - TEST\TEST2.ps1:105 char:13
+     $deduped | Export-Csv $SaveFileDialog.filename -NoTypeInformation
+                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Export-Csv], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.ExportCsvCommand

Get-ChildItem : Second path fragment must not be a drive or UNC name.
Parameter name: path2
At \\Mbp-nt01\dma\Digitial Marketing\___Shared folder for Email Team\_Fun_Template_2018\_remove dup - TEST\TEST2.ps1:107 char:13
+     $Cleanup = Get-ChildItem . $SaveFileDialog.filename -rec
+                ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (\\Mbp-nt01\dma\...move dup - TEST:String) [Get-ChildItem], ArgumentException
    + FullyQualifiedErrorId : DirArgumentError,Microsoft.PowerShell.Commands.GetChildItemCommand
Martin
  • 3
  • 3
  • 1
    Please post the (full) error messages you get – Mathias R. Jessen Mar 06 '19 at 13:42
  • 2
    As an aside: `LoadWithPartialName` has been deprecated. Use `Add-Type -AssemblyName System.Windows.Forms` instead – Theo Mar 06 '19 at 13:48
  • @Mathias R. Jessen Hi, I have updated the question with the errors, thanks. – Martin Mar 06 '19 at 13:49
  • 1
    Variable `$SendFileDialog` is local to the `BrowseSend` function, `$SuppressionFileDialog` is local to the `BrowseSuppression` function. Why do you think they live on in the rest of your script? Also, in function `Dedupe` you have a typo: `$fileB = Import-csv $SupressionFileDialog.filename`. There are 2 `p`s in Suppression – Theo Mar 06 '19 at 13:55
  • Hi Theo, this is the part I unsure of, I thought buy setting a global variable `$Global:SelectedSendFile = $null` then using `$SelectedSendFile = $SendFileDialog.filename` would set a global variable. However I assumed the fault was in these variables but even when all the processes were combined into 1 function I still saw the same errors. – Martin Mar 06 '19 at 14:05
  • 1
    @Martin I'd strongly recommend you pass the values you need in the function as parameter argument, rather than relying on global variables – Mathias R. Jessen Mar 06 '19 at 14:21
  • 1
    @Martin - for a variable to be used globally, you must ALWAYS use the `$Global:` scope modifier - every time. – Lee_Dailey Mar 06 '19 at 14:21
  • @Lee_Dailey: Excellent point: If you want to _set_ a global variable, you must use `$global:`, and that is likely the root cause of the problem at hand (but note that you don't (necessarily) need `$global:` to _get_ a global variable's value). – mklement0 Mar 06 '19 at 14:33
  • @Martin, I hope that Lee's comment in combination with the linked answer is sufficient to solve your problem. – mklement0 Mar 06 '19 at 14:35
  • @mklement0 - while it's true that _sometimes_ one can get away with not specifying the scope on a manually scoped $Var ... that leaves one open to the times when the scope _will_ be required. [*frown*] so it seems most reliable to always use it when you want to deal with the manually scoped version of the $Var. ///// of course, your point that it really otta be avoided is the best solution to that nasty uncertainty about scope. [*grin*] – Lee_Dailey Mar 06 '19 at 16:18
  • @Lee_Dailey: Yes, I agree that use of global variables should be avoided altogether and that if you do use them, _it is best_ to always use `$global:` for conceptual clarity and to avoid subtle bugs. However, since your comment seemed to imply that using `$global:` is a (technical) _must_, I felt the need to clarify. – mklement0 Mar 06 '19 at 16:26

0 Answers0