Cannot upload files via Powershell GUI

Kasper Katzmann
Kasper Katzmann used Ask the Experts™
on
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?
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Most Valuable Expert 2018
Distinguished Expert 2018
Commented:
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

ste5anSenior Developer
Commented:
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 KatzmannSeniorkonsulent

Author

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 KatzmannSeniorkonsulent

Author

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 KatzmannSeniorkonsulent

Author

Commented:
Thank you both - I really appriciate the help.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial