How do I get DatePicker and TextBox information fr

2019-09-15 20:11发布

问题:

I am new to scripting (first year) and this is my first time trying to take a WPF application from VisualStudio and turn its XAML code into something that I can use with Powershell. I'm attempting to create a small application that will allow me to enter an Active Directory username into a TextBox field and select a date from a DatePicker object and then turn both of those pieces of information into Powershell variables. From there, I enable VPN access for the AD user and then use the date as a "cutoff date" at which point I will disable the user's access. Both of those variables will also be outputted to a .csv file on our server that will be read daily by a Scheduled Task. If the cutoff date matches the current day, another script will be triggered that disables the user's VPN access. (That scheduled powershell script is not included here and will be written later.)

Please look over my code and help me figure out why I cannot retrieve the information from the TextBox and DatePicker to fill my Powershell variables! My issue seems to be in the "Actually make the objects work" section. I get an error that "WPFtextbox_Username.Text" and "DatePicker.SelectedDate.Value.Date.ToShortDateString" are not valid in Powershell, and so the variables $ADUser and $ExpirationDate are empty when I am writing to the .csv file. Any help will be appreciated by this scripting noob!

Credit to https://foxdeploy.com/2015/04/16/part-ii-deploying-powershell-guis-in-minutes-using-visual-studio/ for the framework for this XAML to Powershell code.

$inputXML = @"
<Window x:Name="AllowVPNWindow" x:Class="AddADUserToVPN.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:AddADUserToVPN"
    mc:Ignorable="d"
    Title="Add VPN Access" Height="365.779" Width="577.356">
  <Grid>
    <Grid.Background>
        <LinearGradientBrush EndPoint="0.5,1"     MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
            <GradientStop Color="Black" Offset="1"/>
            <GradientStop Color="#FF781515" Offset="0.077"/>
        </LinearGradientBrush>
    </Grid.Background>
    <Label x:Name="label_username" Content="Username:" HorizontalAlignment="Left" Height="39" Margin="19,20,0,0" VerticalAlignment="Top" Width="95" Foreground="White" FontWeight="Bold" FontSize="16"/>
    <Label x:Name="label_VPNCutoffDate" Content="VPN Access Cutoff Date:" HorizontalAlignment="Left" Height="63" Margin="19,80,0,0" VerticalAlignment="Top" Width="204" Foreground="White" FontWeight="Bold" FontSize="16" />
    <TextBox x:Name="textBox_Username" HorizontalAlignment="Left" Height="22" Margin="25,52,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="125"/>
    <Button x:Name="button_AddUser" Content="Add User" HorizontalAlignment="Left" Height="37" Margin="445,37,0,0" VerticalAlignment="Top" Width="80" FontSize="16">
        <Button.Effect>
            <DropShadowEffect/>
        </Button.Effect>
    </Button>
    <TextBlock x:Name="textBlock_Instructions" HorizontalAlignment="Left" Height="84" Margin="299,215,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="244" Foreground="White" FontSize="16"><Run Text="Enter a "/><Run Foreground="#FF26D636" Text="valid"/><Run Text=" Active Directory username and select the date that the user's VPN access will "/><Run Foreground="#FF26D636" Text="end"/><Run Text=". "/></TextBlock>
    <DatePicker x:Name="DatePicker" HorizontalAlignment="Left" Height="34" Margin="25,116,0,0" VerticalAlignment="Top" Width="125" FontSize="16"/>
  </Grid>
</Window>
"@        

$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N'  -replace '^<Win.*', '<Window'


[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML
#Read XAML

$reader=(New-Object System.Xml.XmlNodeReader $xaml) 
try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
catch{Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed."}

#===========================================================================
# Store Form Objects In PowerShell
#===========================================================================

$xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name)}

Function Get-FormVariables{
if ($global:ReadmeDisplay -ne $true){Write-host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow;$global:ReadmeDisplay=$true}
write-host "Found the following interactable elements from our form" -ForegroundColor Cyan
get-variable WPF*
}

Get-FormVariables

#===========================================================================
# Actually make the objects work
#===========================================================================

##### Grab information from the Text Box and from the DatePicker objects


function Get-FormFields {
$ADUser = if (WPFtextbox_Username.Text -ne $null){$ADUser = WPFtextbox_Username.Text}

            else{$wshell = New-Object -ComObject Wscript.Shell
                 $wshell.Popup("Enter valid username.",0,"Try Again")
                 &Rest}


$ExpirationDate = (DatePicker.SelectedDate.Value.Date.ToShortDateString)
}





$WPFbutton_AddUser.Add_Click({
    #Resolve Form Settings
    Get-FormFields

    ##### Add VPN permission to the selected user
    Set-ADUser $ADUser -Replace @{msnpallowdialin=$true} 



    ##### Append ADUsername and Expiration Date to .csv file
    "$ADUser, $ExpirationDate" | out-file -FilePath \\10.48.0.200\d$\adusertest.txt -append -width 200


$Form.Close()})


#===========================================================================
# Shows the form
#===========================================================================
write-host "To show the form, run the following" -ForegroundColor Cyan

function Show-Form{
$Form.ShowDialog() | out-null

}

Show-Form

回答1:

Found some other things that didn't look write in your code such as missing parenthesis () in a method call and more missing dollar signs ($) in variables as well as a mistyped name for your datepicker (should be WPFDatepicker). I ran the updated code below and it produced the expected results in the text file.

$inputXML = @"
<Window x:Name="AllowVPNWindow" x:Class="AddADUserToVPN.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:AddADUserToVPN"
    mc:Ignorable="d"
    Title="Add VPN Access" Height="365.779" Width="577.356">
  <Grid>
    <Grid.Background>
        <LinearGradientBrush EndPoint="0.5,1"     MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
            <GradientStop Color="Black" Offset="1"/>
            <GradientStop Color="#FF781515" Offset="0.077"/>
        </LinearGradientBrush>
    </Grid.Background>
    <Label x:Name="label_username" Content="Username:" HorizontalAlignment="Left" Height="39" Margin="19,20,0,0" VerticalAlignment="Top" Width="95" Foreground="White" FontWeight="Bold" FontSize="16"/>
    <Label x:Name="label_VPNCutoffDate" Content="VPN Access Cutoff Date:" HorizontalAlignment="Left" Height="63" Margin="19,80,0,0" VerticalAlignment="Top" Width="204" Foreground="White" FontWeight="Bold" FontSize="16" />
    <TextBox x:Name="textBox_Username" HorizontalAlignment="Left" Height="22" Margin="25,52,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="125"/>
    <Button x:Name="button_AddUser" Content="Add User" HorizontalAlignment="Left" Height="37" Margin="445,37,0,0" VerticalAlignment="Top" Width="80" FontSize="16">
        <Button.Effect>
            <DropShadowEffect/>
        </Button.Effect>
    </Button>
    <TextBlock x:Name="textBlock_Instructions" HorizontalAlignment="Left" Height="84" Margin="299,215,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="244" Foreground="White" FontSize="16"><Run Text="Enter a "/><Run Foreground="#FF26D636" Text="valid"/><Run Text=" Active Directory username and select the date that the user's VPN access will "/><Run Foreground="#FF26D636" Text="end"/><Run Text=". "/></TextBlock>
    <DatePicker x:Name="DatePicker" HorizontalAlignment="Left" Height="34" Margin="25,116,0,0" VerticalAlignment="Top" Width="125" FontSize="16"/>
  </Grid>
</Window>
"@        

$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N'  -replace '^<Win.*', '<Window'


[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML
#Read XAML

$reader=(New-Object System.Xml.XmlNodeReader $xaml) 
try{$Form=[Windows.Markup.XamlReader]::Load( $reader )}
catch{Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed."}

#===========================================================================
# Store Form Objects In PowerShell
#===========================================================================

$xaml.SelectNodes("//*[@Name]") | %{Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name)}

Function Get-FormVariables{
    if ($global:ReadmeDisplay -ne $true){
        Write-host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow
        $global:ReadmeDisplay=$true
    }
    write-host "Found the following interactable elements from our form" -ForegroundColor Cyan
    get-variable WPF*
}

Get-FormVariables

#===========================================================================
# Actually make the objects work
#===========================================================================

##### Grab information from the Text Box and from the DatePicker objects

function Get-FormFields {
    $Script:ADUser = if ($WPFtextbox_Username.Text -ne $null){
        $WPFtextbox_Username.Text
    }

    else{
        $wshell = New-Object -ComObject Wscript.Shell
        $wshell.Popup("Enter valid username.",0,"Try Again")
    }


    $Script:ExpirationDate = $WPFDatePicker.SelectedDate.ToShortDateString()
}

$WPFbutton_AddUser.Add_Click({
    #Resolve Form Settings
    Get-FormFields

    ##### Add VPN permission to the selected user
    #Set-ADUser $ADUser -Replace @{msnpallowdialin=$true} 



    ##### Append ADUsername and Expiration Date to .csv file
    "$ADUser, $ExpirationDate" | out-file -FilePath adusertest.txt -append -width 200


$Form.Close()})


#===========================================================================
# Shows the form
#===========================================================================
write-host "To show the form, run the following" -ForegroundColor Cyan

function Show-Form{
$Form.ShowDialog() | out-null

}

Show-Form