ChrisPEditor
ChrisPEditor

Reputation: 215

Variable is an empty string even after writing the string to host

I'm trying to build a little app to help admins swap powerapps ownership around in PowerShell. I'm sure this is me misunderstanding how scopes work in PowerShell but I'm stumped and need a little help.

The app is pretty simple, it queries the PowerApp environment for a list of apps, their owners, and their GUIDs and presents them in a datagridview. Users select the app they're going to change, click a button, put an email address in, and then click another button. On that click, the app grabs the user's GUID from AAD and then runs a command to flip ownership of the app to that user's GUID.

But for some reason, the second function keeps reporting that the GUID and App Name I collected in the first screen are empty strings.

Here's the whole thing (minus credential info, natch):

#Get Apps on environment
$apps = Get-AdminPowerApp -EnvironmentName $powerAppEnv

#Form Details
$ChangePowerAppOwnership            = New-Object system.Windows.Forms.Form
$ChangePowerAppOwnership.ClientSize = New-Object System.Drawing.Point(500,300)
$ChangePowerAppOwnership.text       = "Change PowerApp Ownership"
$ChangePowerAppOwnership.TopMost    = $false

$appsLabel                          = New-Object system.Windows.Forms.Label
$appsLabel.text                     = "Available Apps"
$appsLabel.AutoSize                 = $true
$appsLabel.width                    = 25
$appsLabel.height                   = 10
$appsLabel.location                 = New-Object System.Drawing.Point(15,20)
$appsLabel.Font                     = New-Object System.Drawing.Font('Segoe UI',10)

$availableApps                      = New-Object system.Windows.Forms.DataGridView
$availableApps.width                = 470
$availableApps.height               = 200
$availableApps.location             = New-Object System.Drawing.Point(15,40)
$availableApps.MultiSelect          = $false
$availableApps.SelectionMode        = "FullRowSelect"
$availableApps.ColumnCount          = 3
$availableApps.ColumnHeadersVisible = $true
$availableApps.Columns[0].Name      = "App Name"
$availableApps.Columns[1].Name      = "Current Owner"
$availableApps.Columns[2].Name      = "GUID"

foreach($app in $apps){
    $availableApps.Rows.Add(@($app.DisplayName,($app.Owner | Select-Object -Expand displayName),$app.AppName))
}

$promptForAdmin                     = New-Object system.Windows.Forms.Button
$promptForAdmin.text                = "Next"
$promptForAdmin.width               = 60
$promptForAdmin.height              = 30
$promptForAdmin.location            = New-Object System.Drawing.Point(424,260)
$promptForAdmin.Font                = New-Object System.Drawing.Font('Segoe UI',10)
$promptForAdmin.Add_Click({ GetNewAdmin $availableApps.SelectedRows})

$adminLabel                         = New-Object system.Windows.Forms.Label
$adminLabel.text                    = "New Administrator"
$adminLabel.AutoSize                = $true
$adminLabel.width                   = 25
$adminLabel.height                  = 10
$adminLabel.location                = New-Object System.Drawing.Point(14,13)
$adminLabel.Font                    = New-Object System.Drawing.Font('Segoe UI',10)

$adminEmailField                    = New-Object system.Windows.Forms.TextBox
$adminEmailField.multiline          = $false
$adminEmailField.width              = 200
$adminEmailField.height             = 20
$adminEmailField.location           = New-Object System.Drawing.Point(135,12)
$adminEmailField.Font               = New-Object System.Drawing.Font('Segoe UI',10)

$changeAppAdmin                     = New-Object system.Windows.Forms.Button
$changeAppAdmin.text                = "Go"
$changeAppAdmin.width               = 60
$changeAppAdmin.height              = 30
$changeAppAdmin.location            = New-Object System.Drawing.Point(424,260)
$changeAppAdmin.Font                = New-Object System.Drawing.Font('Segoe UI',10)

$ChangePowerAppOwnership.controls.AddRange(@($appsLabel,$availableApps,$promptForAdmin))
$ChangePowerAppOwnership.ShowDialog()

function GetNewAdmin {
    param($selectedRows)
    $selectedAppGuid = $selectedRows | ForEach-Object{ $_.Cells[2].Value }
    $selectedAppName = $selectedRows | ForEach-Object{ $_.Cells[0].Value }
    Write-Host "Selected App GUID: $selectedAppGuid" #this and the following command show values
    Write-Host "Selected App Name: $selectedAppName"
    $appsLabel.Visible = $false
    $availableApps.Visible = $false
    $promptForAdmin.Visible = $false

    $changeAppAdmin.Add_Click( { AssignNewAdmin $selectedAppGuid $selectedAppName $adminEmailField.Text} )

    $ChangePowerAppOwnership.controls.AddRange(@($adminLabel,$adminEmailField,$changeAppAdmin))
}

function AssignNewAdmin { 
    param(
        $selectedAppGuid,
        $selectedAppName,
        $newAdminEmail
    )

    Write-Host "AppID: $selectedAppGuid" #this is always empty

    Connect-AzureAD -Credential $credentials
    $user = Get-AzureADUser -ObjectId $newAdminEmail
    $newAppOwnerGuid = $user | select ObjectId
    $newAppOwnerName = $user | select DisplayName

    $msgBoxMessage = "Are you sure you want to grant ownership of $selectedAppName to $newAppOwnerName`?"
    $msgBoxInput = [System.Windows.Forms.MessageBox]::Show($msgBoxMessage,"Confirm","YesNo","Error")
    switch ($msgBoxInput){
        'Yes'{
            Set-AdminPowerAppOwner -AppName $selectedAppGuid -EnvironmentName $powerAppEnv -AppOwner $newAppOwnerGuid
            # try{
                
            #     $ChangePowerAppOwnership.Close()
            # }
            # catch{
            #     Write-Host "Could not update this app's administrator role."
            # }
        }
        'No' {
            $ChangePowerAppOwnership.Close()
        }
    }
}

Upvotes: 0

Views: 278

Answers (2)

ChrisPEditor
ChrisPEditor

Reputation: 215

Courtesy of Jeroen Mostert's comment, adding GetNewClosure to my second Add_Click function did the trick.

Upvotes: 0

T-Me
T-Me

Reputation: 1884

Move the functions to the top or at least higher than $ChangePowerAppOwnership.ShowDialog() or the script wont find them(the execution stops till you close the Form...).
The same goes for the function AssignNewAdmin as it is used in GetNewAdmin but defined later.

Upvotes: 1

Related Questions