Cannot upload files via Powershell GUI

I have a Powershell script that opens a GUI where I am supposed to upload a file from.

The script looks like this:
$Button = 'system.Windows.Forms.Button'
$SanSerif10Bold = 'Microsoft Sans Serif,10,style=Bold'
$sanSerif10 = 'Microsoft Sans Serif,10'
$SysDrawPoint = 'System.Drawing.Point'
# InitialDirectory not defined in submitted code
$InitialDirectory = $env:USERPROFILE #dummy initial directory
#filepath missing from submitted Code
$FilePath = $env:USERPROFILE #dummy Filepath

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

#region begin GUI{ 

$PuzzelFileUpload                = New-Object -TypeName system.Windows.Forms.Form
$PuzzelFileUpload.ClientSize     = '400,124'
$PuzzelFileUpload.text           = 'Puzzel File Uploader'
$PuzzelFileUpload.TopMost        = $false

$txtFileName                     = New-Object -TypeName system.Windows.Forms.TextBox
$txtFileName.multiline           = $false
$txtFileName.width               = 280
$txtFileName.height              = 20
$txtFileName.location            = New-Object -TypeName $SysDrawPoint -ArgumentList (107,39)
$txtFileName.Font                = $sanSerif10

$btnFileBrowser                  = New-Object -TypeName $Button
$btnFileBrowser.BackColor        = '#858585'
$btnFileBrowser.text             = 'BROWSE'
$btnFileBrowser.width            = 79
$btnFileBrowser.height           = 38
$btnFileBrowser.location         = New-Object -TypeName $SysDrawPoint -ArgumentList (16,25)
$btnFileBrowser.Font             = $SanSerif10Bold
$btnFileBrowser.ForeColor        = '#ffffff'

$lblFileName                     = New-Object -TypeName system.Windows.Forms.Label
$lblFileName.text                = 'Filnavn'
$lblFileName.AutoSize            = $true
$lblFileName.width               = 25
$lblFileName.height              = 10
$lblFileName.location            = New-Object -TypeName $SysDrawPoint -ArgumentList (110,21)
$lblFileName.Font                = $sanSerif10

$btnUpload                       = New-Object -TypeName $Button
$btnUpload.BackColor             = '#7ed321'
$btnUpload.text                  = 'Upload'
$btnUpload.width                 = 96
$btnUpload.height                = 30
$btnUpload.location              = New-Object -TypeName $SysDrawPoint -ArgumentList (291,78)
$btnUpload.Font                  = $SanSerif10Bold
$btnUpload.ForeColor             = '#000000'

$PuzzelFileUpload.controls.AddRange(@($txtFileName,$btnFileBrowser,$lblFileName,$btnUpload))

#region gui events {
$btnFileBrowser.Add_Click({
Add-Type -AssemblyName System.windows.forms | Out-Null
    
$OpenFileDialog = New-Object -TypeName System.Windows.Forms.OpenFileDialog
$OpenFileDialog.initialDirectory = $initialDirectory
$OpenFileDialog.filter = 'CSV (*.csv)| *.csv'
$OpenFileDialog.ShowDialog() | Out-Null
$filePath = $OpenFileDialog.filename

$txtFileName.Text = $filePath 
$form.Refresh()
})
$btnUpload.Add_Click({
$destPath = '\\server1.my.domain.dk\Puzzel\'

Copy-Item -Path $filePath -Destination $destPath
})
#endregion events }

#endregion GUI }


#Write your logic code here

$null = $PuzzelFileUpload.ShowDialog()

Open in new window


But... when I try to upload a file, strange things happen.
First I get this error message:
You cannot call a method on a null-valued expression.
At line:66 char:1
+ $form.Refresh()
+ ~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

Open in new window


And when I press Upload, a folder is created with my username, instead of the file I have selected.
The selected file is chosen from my Documents folder.

Any idea what's going on and why?
Kasper KatzmannSeniorkonsulentAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

oBdACommented:
Issue 1: the form you created is not in $form, it's in $PuzzelFileUpload.
Issue 2: that's simply the path from line 8 (which isn't required at all). The btnFileBrowser scriptblock sets the $txtFileName variable only in its local scope, so what you see in btnUpload is the original variable from the script scope. You need to read the path from the form.
$Button = 'system.Windows.Forms.Button'
$SanSerif10Bold = 'Microsoft Sans Serif,10,style=Bold'
$sanSerif10 = 'Microsoft Sans Serif,10'
$SysDrawPoint = 'System.Drawing.Point'
# InitialDirectory not defined in submitted code
$InitialDirectory = $env:USERPROFILE #dummy initial directory

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

#region begin GUI{ 

$PuzzelFileUpload                = New-Object -TypeName system.Windows.Forms.Form
$PuzzelFileUpload.ClientSize     = '400,124'
$PuzzelFileUpload.text           = 'Puzzel File Uploader'
$PuzzelFileUpload.TopMost        = $false

$txtFileName                     = New-Object -TypeName system.Windows.Forms.TextBox
$txtFileName.multiline           = $false
$txtFileName.width               = 280
$txtFileName.height              = 20
$txtFileName.location            = New-Object -TypeName $SysDrawPoint -ArgumentList (107,39)
$txtFileName.Font                = $sanSerif10

$btnFileBrowser                  = New-Object -TypeName $Button
$btnFileBrowser.BackColor        = '#858585'
$btnFileBrowser.text             = 'BROWSE'
$btnFileBrowser.width            = 79
$btnFileBrowser.height           = 38
$btnFileBrowser.location         = New-Object -TypeName $SysDrawPoint -ArgumentList (16,25)
$btnFileBrowser.Font             = $SanSerif10Bold
$btnFileBrowser.ForeColor        = '#ffffff'

$lblFileName                     = New-Object -TypeName system.Windows.Forms.Label
$lblFileName.text                = 'Filnavn'
$lblFileName.AutoSize            = $true
$lblFileName.width               = 25
$lblFileName.height              = 10
$lblFileName.location            = New-Object -TypeName $SysDrawPoint -ArgumentList (110,21)
$lblFileName.Font                = $sanSerif10

$btnUpload                       = New-Object -TypeName $Button
$btnUpload.BackColor             = '#7ed321'
$btnUpload.text                  = 'Upload'
$btnUpload.width                 = 96
$btnUpload.height                = 30
$btnUpload.location              = New-Object -TypeName $SysDrawPoint -ArgumentList (291,78)
$btnUpload.Font                  = $SanSerif10Bold
$btnUpload.ForeColor             = '#000000'

$PuzzelFileUpload.controls.AddRange(@($txtFileName, $btnFileBrowser, $lblFileName, $btnUpload))

#region gui events {
$btnFileBrowser.Add_Click({
	Add-Type -AssemblyName System.windows.forms | Out-Null
		
	$OpenFileDialog = New-Object -TypeName System.Windows.Forms.OpenFileDialog
	$OpenFileDialog.initialDirectory = $initialDirectory
	$OpenFileDialog.filter = 'CSV (*.csv)| *.csv'
	$OpenFileDialog.ShowDialog() | Out-Null
	$filePath = $OpenFileDialog.filename

	$txtFileName.Text = $filePath 
	$PuzzelFileUpload.Refresh()
})
$btnUpload.Add_Click({
	$destPath = '\\server1.my.domain.dk\Puzzel\'
	Copy-Item -Path $txtFileName.Text -Destination $destPath
})
#endregion events }

#endregion GUI }


#Write your logic code here

$null = $PuzzelFileUpload.ShowDialog()

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
ste5anSenior DeveloperCommented:
hmm, you mixed different sources from other posts. Thus the error. And stick to one code convention. E.g.

Set-StrictMode -Version 2
Clear-Host

Function Initialize-WinForms() {
    Add-Type -AssemblyName System.Windows.Forms
    [System.Windows.Forms.Application]::EnableVisualStyles()
}

Function Create-Form() {
    $form = New-Object System.Windows.Forms.Form -Property @{
        ClientSize = '400, 124'
        Text       = 'Puzzel File Uploader'
        TopMost    = $false
    }

    $btnFileBrowser = New-Object System.Windows.Forms.Button -Property @{
        BackColor = '#858585'
        Text      = 'BROWSE'
        Width     = 79
        Height    = 38
        Location  = New-Object System.Drawing.Point(16, 25)
        Font      = 'Microsoft Sans Serif, 10, style=Bold'
        ForeColor = '#ffffff'
        Parent    = $form
    }

    $btnUpload = New-Object System.Windows.Forms.Button -Property @{
        BackColor = '#7ed321'
        text      = 'Upload'
        width     = 96
        height    = 30
        location  = New-Object System.Drawing.Point(291, 78)
        Font      = 'Microsoft Sans Serif, 10, style=Bold'
        ForeColor = '#000000'
        Parent    = $form
    }

    $openFileDialog = New-Object System.Windows.Forms.OpenFileDialog -Property @{
        InitialDirectory = 'C:\Temp\'
        Filter           = 'All Files|*.*'
    }

    $txtFileName = New-Object System.Windows.Forms.TextBox -Property @{
        Multiline = $false
        Width     = 280
        Height    = 20
        Location  = New-Object System.Drawing.Point(107, 39)
        Font      = 'Microsoft Sans Serif, 10'
        Parent    = $form
    }

    $btnFileBrowser.Add_Click($btnFileBrowser_OnClick.GetNewClosure())
    $btnUpload.Add_Click($btnUpload_OnClick.GetNewClosure())
    $form
}

$btnFileBrowser_OnClick = {
    $openFileDialog.ShowDialog()
    $txtFileName.Text = $openFileDialog.Filename
}

$btnUpload_OnClick = {
    Copy-Item -Path $txtFileName.Text -Destination '\\server1.my.domain.dk\Puzzel\'
}

Initialize-WinForms
$form = Create-Form
$form.ShowDialog()

Open in new window

p.s. consider using Visual Studio Code as editor. Cause it built-in PowerShell support, especially code formatting.
Kasper KatzmannSeniorkonsulentAuthor Commented:
Thank you both for clarifying. This is my first attempt to make a powershell gui, so any help and claryfication is appriciated.

@oBda
Your changes did the job, but as with so many other aspects in life, one answer rises two new questions :-)
I have tried to add a simple error handling, where I check if the source and destination files have the same hash.
When the form is loaded, I dont want to show any text in $lblResult, but after I have submitted the file, I want to show one of the messages, depending on the result of the hash-check. But nothing happens.

With my limited understanding of the GUI concept, I would guess that I could put the refresh part in where i did, but...
$sourceHash = Get-FileHash $FilePath
    $destHash   = Get-FileHash "$destPath\Test.csv"

        if($sourceHash -eq $destHash)
        {
            $lblResult.text       = "Filen er nu overført til $FilePath"
            $lblResult.ForeColor  = '#009933'
	         $PuzzelFileUpload.Refresh()
        }
        ELSE
        {
            $lblResult.text       = "Filen er IKKE nu overført"
            $lblResult.ForeColor  = '#ff0000'
	         $PuzzelFileUpload.Refresh()
        }

Open in new window

Complete script here:
$Button = 'system.Windows.Forms.Button'
$SanSerif10Bold = 'Microsoft Sans Serif,10,style=Bold'
$sanSerif10 = 'Microsoft Sans Serif,10'
$sanSerif8 = 'Microsoft Sans Serif,8'
$SysDrawPoint = 'System.Drawing.Point'
# InitialDirectory not defined in submitted code
$InitialDirectory = $env:USERPROFILE #dummy initial directory

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles()

#region begin GUI{ 

$PuzzelFileUpload                = New-Object -TypeName system.Windows.Forms.Form
$PuzzelFileUpload.ClientSize     = '400,124'
$PuzzelFileUpload.text           = 'Puzzel File Uploader'
$PuzzelFileUpload.TopMost        = $false

$txtFileName                     = New-Object -TypeName system.Windows.Forms.TextBox
$txtFileName.multiline           = $false
$txtFileName.width               = 280
$txtFileName.height              = 20
$txtFileName.location            = New-Object -TypeName $SysDrawPoint -ArgumentList (107,39)
$txtFileName.Font                = $sanSerif10

$btnFileBrowser                  = New-Object -TypeName $Button
$btnFileBrowser.BackColor        = '#858585'
$btnFileBrowser.text             = 'BROWSE'
$btnFileBrowser.width            = 79
$btnFileBrowser.height           = 38
$btnFileBrowser.location         = New-Object -TypeName $SysDrawPoint -ArgumentList (16,25)
$btnFileBrowser.Font             = $SanSerif10Bold
$btnFileBrowser.ForeColor        = '#ffffff'

$lblFileName                     = New-Object -TypeName system.Windows.Forms.Label
$lblFileName.text                = 'Filnavn'
$lblFileName.AutoSize            = $true
$lblFileName.width               = 25
$lblFileName.height              = 10
$lblFileName.location            = New-Object -TypeName $SysDrawPoint -ArgumentList (110,21)
$lblFileName.Font                = $sanSerif10

$lblResult                       = New-Object -TypeName system.Windows.Forms.Label
$lblResult.text                  = ''
$lblResult.width                 = 270
$lblResult.height                = 30
$lblResult.location              = New-Object -TypeName $SysDrawPoint -ArgumentList (10,78)
$lblResult.Font                  = $SanSerif8
$lblResult.ForeColor             = ''

$btnUpload                       = New-Object -TypeName $Button
$btnUpload.BackColor             = '#7ed321'
$btnUpload.text                  = 'Upload'
$btnUpload.width                 = 96
$btnUpload.height                = 30
$btnUpload.location              = New-Object -TypeName $SysDrawPoint -ArgumentList (291,78)
$btnUpload.Font                  = $SanSerif10Bold
$btnUpload.ForeColor             = '#000000'

$PuzzelFileUpload.controls.AddRange(@($txtFileName, $btnFileBrowser, $lblFileName, $lblResult, $btnUpload))

#region gui events {
$btnFileBrowser.Add_Click({
	Add-Type -AssemblyName System.windows.forms | Out-Null
		
	$OpenFileDialog = New-Object -TypeName System.Windows.Forms.OpenFileDialog
	$OpenFileDialog.initialDirectory = $initialDirectory
	$OpenFileDialog.filter = 'CSV (*.csv)| *.csv'
	$OpenFileDialog.ShowDialog() | Out-Null
	$filePath = $OpenFileDialog.filename

	$txtFileName.Text = $filePath 
	$PuzzelFileUpload.Refresh()
})
$btnUpload.Add_Click({
	$destPath = '\\server1.my.domain.dk\Puzzel\'
    
    Copy-Item -Path $txtFileName.Text -Destination $destPath

    $sourceHash = Get-FileHash $FilePath
    $destHash   = Get-FileHash "$destPath\Test.csv"

        if($sourceHash -eq $destHash)
        {
            $lblResult.text       = "Filen er nu overført til $FilePath"
            $lblResult.ForeColor  = '#009933'
	        $PuzzelFileUpload.Refresh()
        }
        ELSE
        {
            $lblResult.text       = "Filen er IKKE nu overført"
            $lblResult.ForeColor  = '#ff0000'
	        $PuzzelFileUpload.Refresh()
        }

})

Open in new window

Kasper KatzmannSeniorkonsulentAuthor Commented:
Found the answer to the last bit... I forgot to remove .text '' and .forecolor '' from
$lblResult                       = New-Object -TypeName system.Windows.Forms.Label
$lblResult.text                  = ''
$lblResult.width                 = 270
$lblResult.height                = 30
$lblResult.location              = New-Object -TypeName $SysDrawPoint -ArgumentList (10,78)
$lblResult.Font                  = $SanSerif8
$lblResult.ForeColor             = ''

Open in new window

Kasper KatzmannSeniorkonsulentAuthor Commented:
Thank you both - I really appriciate the help.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.