Ad Space here

Welcome Guest! To enable all features please Login or Register.

Notification

Icon
Error

Share
Options
Go to last post Go to first unread
Dustin Higgins  
#1 Posted : Sunday, March 01, 2020 9:05:47 PM(UTC)
Dustin Higgins

Rank: Advanced Member

Groups: Registered
Joined: 7/1/2018(UTC)
Posts: 63
_United States

Thanks: 1 times
Was thanked: 6 time(s) in 6 post(s)

Quickly Build User Interfaces

for System Administration Tools in PowerShell

I took a few days to learn about the Windows Presentation Framework in PowerShell.  It is unbelievable how quickly you can build user interfaces for system administration tools.

Please see my video that details the code and application below:

​​​​​​​

Code:
function Write-DatagridToExcel
{
    <#
    .SYNOPSIS
    A function to write the DataGrid contents to Excel
    .DESCRIPTION
    A function to write the DataGrid contents to Excel
    #>
    param (
        [Parameter(Mandatory=$true)]
        [System.Windows.Controls.DataGrid]$DataGridForExcel
    )
    # Get the COM object
    $Excel = New-Object -ComObject Excel.Application
    $Excel.Visible = $true
    $Workbook = $Excel.Workbooks.Add()
    $Worksheet = $Workbook.WorkSheets.Item(1)
    # Get the 1st Object
    $FirstOne = $DataGridForExcel.Items | Select-Object -First 1
    # Add the Column Headers
    $Index = 0
    foreach ($p in $FirstOne.PSObject.Properties) {
        $Index++
        $Worksheet.Cells(1,$Index) = $p.Name
    }
    # Add the Rows
    $RowCounter = 1
    foreach ($i in $DataGridForExcel.Items) {
        $RowCounter++
        $ColumnCounter = 0
        foreach ($p in $FirstOne.PSObject.Properties) {
            $ColumnCounter++
            $Worksheet.Cells($RowCounter, $ColumnCounter) = $i.($p.Name)
        }
    }
}

Code:
function Write-LogRichTextBox
{
    <#
    .SYNOPSIS
    A function to log to the rich text box
    .DESCRIPTION
    A function to log to the rich text box
    #>
    param (
        [Parameter(Mandatory=$true)]
        [string]$LogString
    )
    # Timestamp the log entry
    $LogEntry = "$((Get-Date -Format "MM-dd-yyyy HH:mm:ss")) $($LogString)`n"
    # Write it to the log box
    $rtbLogWindow.AppendText($LogEntry)
    $rtbLogWindow.ScrollToEnd()
}

Code:
function Load-DataGrid
{
    <#
    .SYNOPSIS
    A function to load the datagrid with objects
    .DESCRIPTION
    A function to load the datagrid with objects
    #>
    param (
        [Parameter(Mandatory=$true)]
        [System.Windows.Controls.DataGrid]$DataGridToLoad,
        [Parameter(Mandatory=$true)]
        [System.Collections.Generic.List[PSObject]]$ObjectList
    )
    # Clear the DataGrid
    $DataGridToLoad.Items.Clear()
    # Remove the current columns
    $ColumnCount = $DataGridToLoad.Columns.Count
    for ($i = 0 ; $i -lt $ColumnCount ; $i++) {
        $DataGridToLoad.Columns.RemoveAt(0)
    }
    # Get the 1st object
    $FirstOne = $ObjectList | Select-Object -First 1
    # Add the properties as columns
    foreach ($p in $FirstOne.PSObject.Properties) {
        $Column = New-Object System.Windows.Controls.DataGridTextColumn
        $Column.Header = $p.Name
        $Column.Binding = New-Object System.Windows.Data.Binding($p.Name)
        $DataGridToLoad.Columns.Add($Column)
    }
    # Add the objects
    foreach ($i in $ObjectList) {
        $DataGridToLoad.AddChild($i)
    }
    # Return the DataGrid
    Return (,($DataGridToLoad))
}

Code:
function Get-ComputerName
{
    <#
    .SYNOPSIS
    A function to get the computer name from a text box.
    .DESCRIPTION
    A function to get the computer name from a text box.  
    Default to the local computer.
    #>
    if ($tbComputer.Text -eq "") {
        $env:COMPUTERNAME
    } else {
        return $tbComputer.Text
    }
}

Code:
function Get-DiskSpace
{
    <#
    .SYNOPSIS
    A simple function to get disk space from a computer and return an object
    .DESCRIPTION
    A simple function to get disk space from a computer and return an object
    #>
    param (
        [Parameter(Mandatory=$true)]
        [string]$Computer
    )
    $Obj = [PSCustomObject]@{
        Computer = $Computer
        Online = $null
        Size = $null
        FreeSpace = $null
        UsedSpace = $null
        PercentFree = $null
    }
    ## CHECK PING STATUS - RETURN IF OFFLINE
    $pingStatus = ping -n 1 -4 $computer
    if ($?) {
        if ($pingStatus -match "unreachable" -or $pingStatus -match "could not find host" -or $pingStatus -match "timed out") {
            $Obj.Online = $false
            return $Obj
        } else {
            $Obj.Online = $true
        }
    } else {
        $Obj.Online = $false
        return $Obj
    }
    # Query the disk space
    $WmiDiskSpace = Get-WmiObject Win32_LogicalDisk -ComputerName $Computer
    foreach ($i in $WmiDiskSpace) {
        if ($i.DeviceId -eq "C:") { 
            $FreeGB = [math]::Round(($i.FreeSpace / 1GB),2)
            $SizeGB = [math]::Round(($i.Size / 1GB),2)
            $Obj.Size = $SizeGB
            $Obj.UsedSpace = [math]::Round(($SizeGB - $FreeGB),2)
            $Obj.FreeSpace = $FreeGB
            $Obj.PercentFree = [math]::Round(($FreeGB / $SizeGB) * 100,2)   
        }
    }
    # Return the Object
    Return $Obj
}

Code:
##################################################
# MAIN
##################################################
# Add the assembly
Add-Type -AssemblyName PresentationFramework
# Directory the script is running from
$ScriptDir = Split-Path $script:MyInvocation.MyCommand.Path
# Read the XML
[xml]$Xaml = gc ("$($ScriptDir)\WPF_App.xml")
$Reader = New-Object System.Xml.XmlNodeReader $Xaml
$Window = [Windows.Markup.XamlReader]::Load($Reader)
# Set variables for all of the controls
$Xaml.SelectNodes("//*[@Name]") | % { Set-Variable -Name "$($_.Name)" -Value $Window.FindName($_.Name) }
# Add the clicks
$btnDiskSpace.Add_Click({
    Write-LogRichTextBox -LogString "Click: $($this.Name)"
    $Obj = Get-DiskSpace (Get-ComputerName)
    $DataGrid = Load-DataGrid -DataGridToLoad $DataGrid -ObjectList $Obj
})
$btnExcel.Add_Click({
    Write-LogRichTextBox -LogString "Click: $($this.Name)"
    Write-DatagridToExcel $DataGrid
})
# Show the window
$Async = $Window.Dispatcher.InvokeAsync({
    $Window.ShowDialog() | Out-Null
})
$Async.Wait() | Out-Null

WPF_App.xml:

Code:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="Window" 
        SizeToContent="Height"
        Title="My First WPF PowerShell App 1.0">
  <Border>
    <Grid ShowGridLines="False">
      <Grid.RowDefinitions>
        <RowDefinition Height="160"/>
        <RowDefinition Height="140"/>
        <RowDefinition Height="280"/>
      </Grid.RowDefinitions>
      <Border Grid.Row="0">
        <Grid ShowGridLines="False">
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
          </Grid.ColumnDefinitions>
          <StackPanel Grid.Column="0">
            <Button Name="btnDiskSpace">Disk Space</Button>
            <Button></Button>
            <Button></Button>
            <Button></Button>
          </StackPanel>
          <StackPanel Grid.Column="1">
            <Button></Button>
            <Button></Button>
            <Button></Button>
            <Button></Button>
          </StackPanel>
          <StackPanel Grid.Column="2">
            <Label>Computer:</Label>
            <TextBox Name="tbComputer"></TextBox>
            <Button Name="btnExcel">Excel</Button>
          </StackPanel>
        </Grid>
      </Border>
      <Border Grid.Row="1">
        <DataGrid Name="DataGrid">
        </DataGrid>
      </Border>    
      <Border Grid.Row="2">
        <Grid ShowGridLines="False">
          <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
          </Grid.ColumnDefinitions>
          <Border Grid.Column="0">
            <RichTextBox Name="rtbLogWindow">
              <FlowDocument>
                <Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray"></Paragraph>
              </FlowDocument>
            </RichTextBox>
          </Border>
          <Border Grid.Column="1">
            <DockPanel>
              <DockPanel.Background>
                <ImageBrush ImageSource="C:\Admin\PowerShell_CinderBlock_GUI.jpg"  Stretch="None" AlignmentX="Center" AlignmentY="Center" />
              </DockPanel.Background>            
            </DockPanel>            
          </Border>
        </Grid>
      </Border>
    </Grid>
  </Border>
  <Window.Resources>
    <LinearGradientBrush x:Key="MyGradientBrush" StartPoint="0,0" EndPoint="1,1">
      <GradientStop Color="White" Offset="0" />
      <GradientStop Color="DarkBlue" Offset=".1" />
      <GradientStop Color="DarkBlue" Offset=".2" />
      <GradientStop Color="DarkBlue" Offset=".3" />
      <GradientStop Color="DarkBlue" Offset=".4" />
      <GradientStop Color="DarkBlue" Offset=".5" />
      <GradientStop Color="DarkBlue" Offset=".6" />
      <GradientStop Color="DarkBlue" Offset=".7" />
      <GradientStop Color="DarkBlue" Offset=".8" />
      <GradientStop Color="DarkBlue" Offset=".9" />
      <GradientStop Color="White" Offset="1" />
    </LinearGradientBrush>
    <Style TargetType="Border">
      <Setter Property="BorderBrush" Value="DarkBlue" />
      <Setter Property="BorderThickness" Value="2" />
      <Setter Property="Margin" Value="2,2,2,2" />   
    </Style>    
    <Style TargetType="Button">
      <Setter Property="Background" Value="{StaticResource MyGradientBrush}" />
      <Setter Property="Height" Value="30" />      
      <Setter Property="Width" Value="200" />
      <Setter Property="Margin" Value="2,2,2,2" />
      <Setter Property="Foreground" Value="White" />
      <Setter Property="VerticalAlignment" Value="Center" />
      <Setter Property="FontSize" Value="20" />
      <Setter Property="FontStyle" Value="Italic" />
      <Setter Property="FontWeight" Value="Bold" />
      <Setter Property="FontFamily" Value="Courier" />      
      <Style.Resources>
        <Style TargetType="Border">
          <Setter Property="CornerRadius" Value="10" />          
        </Style>
      </Style.Resources>
    </Style>
    <Style TargetType="Label">
      <Setter Property="Foreground" Value="DarkBlue" />
      <Setter Property="Margin" Value="2,2,2,2" />
      <Setter Property="FontSize" Value="20" />
      <Setter Property="FontStyle" Value="Italic" />
      <Setter Property="FontWeight" Value="Bold" />
      <Setter Property="FontFamily" Value="Courier" />
      <Setter Property="HorizontalAlignment" Value="Center" />
    </Style>
    <Style TargetType="TextBox">
      <Setter Property="Width" Value="200" />
      <Setter Property="Background" Value="White" />
      <Setter Property="Foreground" Value="DarkBlue" />
      <Setter Property="Margin" Value="2,2,2,2" />
      <Setter Property="FontSize" Value="20" />
      <Setter Property="FontStyle" Value="Italic" />
      <Setter Property="FontWeight" Value="Bold" />
      <Setter Property="FontFamily" Value="Courier" />
      <Setter Property="HorizontalAlignment" Value="Center" />   
    </Style>
    <Style TargetType="RichTextBox">
      <Setter Property="IsReadOnly" Value="True" />
      <Setter Property="VerticalScrollBarVisibility" Value="Visible" />
    </Style>
    <Style TargetType="DataGrid">
      <Setter Property="IsReadOnly" Value="True" />
      <Setter Property="SelectionMode" Value="Single" />
      <Setter Property="SelectionUnit" Value="FullRow" />
      <Setter Property="CanUserReorderColumns" Value="False" />
      <Setter Property="CanUserResizeColumns" Value="False" />
      <Setter Property="Background" Value="White" />
      <Setter Property="RowBackground" Value="LightBlue" />
      <Setter Property="AlternatingRowBackground" Value="LightCyan" />
      <Setter Property="AlternatingRowBackground" Value="Cyan" />
      <Setter Property="Foreground" Value="Black" />
    </Style>
    <Style TargetType="DataGridRow">
      <Setter Property="FontSize" Value="14" />
      <Setter Property="FontFamily" Value="Arial" />
      <Setter Property="Foreground" Value="Black" />
      <Setter Property="Background" Value="White" />
    </Style>  
    <Style TargetType="DataGridColumnHeader">
      <Setter Property="FontSize" Value="14" />
      <Setter Property="FontFamily" Value="Arial" />
      <Setter Property="FontWeight" Value="Bold" />
    </Style>   
  </Window.Resources>
</Window>

Follow Dustin Higgins ​​​​​​​on Twitter and Instagram

Edited by user Monday, March 23, 2020 1:06:55 AM(UTC)  | Reason: Not specified

Sponsor
Ad Space here
Rss Feed  Atom Feed
Users browsing this topic
Forum Jump  
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.