Functions/Public/Start-COVProfileRemovalForm.ps1

function Start-COVProfileRemovalForm {

    If (-not(Get-InstalledModule Userprofile -ErrorAction silentlycontinue)) {
        Install-Module Userprofile -Confirm:$False -Force -Verbose

    }
  

    $inputXML = @"
<Window x:Class="Profile_Removal_Form.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:Profile_Removal_Form" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800" ResizeMode="NoResize" WindowStyle="None" Background="#181735" WindowStartupLocation="CenterScreen">
 
 
    <Grid>
 
        <Grid.RowDefinitions>
            <RowDefinition Height="25"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="50"/>
            <RowDefinition Height="auto"/>
 
 
        </Grid.RowDefinitions>
 
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
 
        <Grid Background="#0F0F2D" Grid.ColumnSpan="2">
 
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto"/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
 
 
            <TextBlock Text="Users Being Removed" Grid.Column="2" Grid.ColumnSpan="5" Grid.RowSpan="3" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="0,0,30,0" FontFamily="Fonts/#Dosis" FontWeight="Medium" FontSize="20" Foreground="#FF0800" />
 
            <TextBlock Text="Users To Keep" Margin="15,0,0,0" Foreground="White" Grid.Column="9" Grid.ColumnSpan="3" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Fonts/#Dosis" FontWeight="Medium" FontSize="20" />
 
 
 
 
        </Grid>
 
 
 
        <ListBox x:Name="Listbox" Grid.Row="1" Grid.RowSpan="6" Margin="0,20,0,0" Width="300" BorderBrush="Black" Background="#FF040303" SelectionMode="Multiple" Foreground="#FF0BE2F1" FontSize="18" FontFamily="Font/#Dosis" />
 
        <ListBox x:Name="Listboxcopy" Grid.Row="1" Grid.Column="1" Grid.RowSpan="6" Margin="0,20,0,0" Width="300" BorderBrush="Black" Background="#FF040303" Foreground="#FF0BE2F1" FontSize="18" FontFamily="Font/#Dosis"/>
 
        <Button x:Name="RetrieveProfilesBtN" Content="Get Profiles" Foreground="White" Grid.Row="2" Background="#FE6584" Margin="360,0,360,20" Grid.ColumnSpan="2" FontWeight="Medium">
            <Button.Resources>
                <Style TargetType="Border">
                    <Setter Property="CornerRadius" Value="5"/>
                </Style>
            </Button.Resources>
        </Button>
 
 
 
        <Button x:Name="AddBtN" Content="--&gt;" FontSize="18" Foreground="White" Grid.Row="3" Background="#FE6584" Margin="360,0,360,20" Grid.ColumnSpan="2" FontWeight="Medium">
            <Button.Resources>
                <Style TargetType="Border">
                    <Setter Property="CornerRadius" Value="5"/>
                </Style>
            </Button.Resources>
        </Button>
 
        <Button x:Name="RemoveBtN" Content="&lt;--" FontSize="18" Foreground="White" Grid.Row="4" Background="#FE6584" Margin="360,0,360,20" Grid.ColumnSpan="2" FontWeight="Medium">
            <Button.Resources>
                <Style TargetType="Border">
                    <Setter Property="CornerRadius" Value="5"/>
                </Style>
            </Button.Resources>
        </Button>
 
        <Button x:Name="ClearBtN" Content="Clear" Foreground="White" Grid.Row="5" Grid.ColumnSpan="2" Background="#FE6584" Margin="360,0,360,20" FontWeight="Medium">
            <Button.Resources>
                <Style TargetType="Border">
                    <Setter Property="CornerRadius" Value="5"/>
                </Style>
            </Button.Resources>
        </Button>
 
 
 
 
        <TextBlock x:Name="RemoteTxTB" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="68,33,0,0" Grid.Row="7" TextWrapping="Wrap" Text="Computer name" FontSize="14" FontFamily="Font/#Dosis" FontWeight="Medium" Foreground="#FFDA29" Visibility="Hidden" />
 
        <TextBox x:Name="RemoteComputerTxT" Margin="191,34,0,0" Grid.Row="7" VerticalAlignment="Top" HorizontalAlignment="Left" Width="100" FontFamily="Font/#Dosis" TextWrapping="Wrap" Text="" Visibility="Hidden" />
 
        <RadioButton x:Name="RemoteRaDBtN" Content="Run Script against remote machine" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="50,13,0,0" Grid.Row="7" FontSize="14" FontFamily="Font/#Dosis" FontWeight="Medium" Foreground="#FFDA29" />
 
        <Button x:Name="SubmitBtN" Content="Submit" Foreground="White" Grid.Row="8" Background="#FE6584" Margin="310,20,10,-22" FontWeight="Medium">
            <Button.Resources>
                <Style TargetType="Border">
                    <Setter Property="CornerRadius" Value="5"/>
                </Style>
            </Button.Resources>
        </Button>
 
 
 
        <Button x:Name="CancelBtN" Content="Cancel" Foreground="White" Grid.Row="8" Background="#FE6584" Margin="21,20,299,-22" FontWeight="Medium" Grid.Column="1" IsCancel="True">
            <Button.Resources>
                <Style TargetType="Border">
                    <Setter Property="CornerRadius" Value="5"/>
                </Style>
            </Button.Resources>
        </Button>
        <RadioButton x:Name="AdminRaDBtN" Content="Include COV admin accounts" HorizontalAlignment="Left" Margin="50,10,0,0" Grid.Row="8" VerticalAlignment="Top" FontSize="14" FontFamily="Font/#Dosis" FontWeight="Medium" Foreground="#FFDA29"/>
 
         
 
 
 
    </Grid>
 
</Window>
"@


    #End Region Xaml Form
 

    #Region "Xaml to Powershell code"

    Add-Type -AssemblyName PresentationFramework

    $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 [System.Management.Automation.MethodInvocationException] {
        Write-Warning "We ran into a problem with the XAML code. Check the syntax for this control..."
        write-host $error[0].Exception.Message -ForegroundColor Red
        if ($error[0].Exception.Message -like "*button*") {
            write-warning "Ensure your &lt;button in the `$inputXML does NOT have a Click=ButtonClick property. PS can't handle this`n`n`n`n"
        }
    }
    catch {
        #if it broke some other way <img draggable="false" role="img" class="emoji" alt="😀" src="https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/svg/1f600.svg">
        Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .net is installed."
    }
 
    $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



    #Endregion "Xaml to Powershell code"

    $wpflistBox.SelectionMode = "Extended"



    #Region "Buttons"
    #Buttons used to perform actions on the form

    #Clear button, removes all items populated by the retrieve button
    $WPFclearBtN.Add_Click({

            $WPFlistBox.items.Clear()
            $WPFlistBoxCopy.items.Clear()
            $WPFRemoteComputerTxT.Clear()
            $WPFRemoteRaDBtN.IsChecked = $false
            $WPFRemoteTxTB.Visibility = "Hidden"
            $WPFRemoteComputerTxT.Visibility = "Hidden"

        })


    $WPFRemoteRaDBtN.Add_Click({

            if ($WPFRemoteRaDBtN.IsChecked -eq $true) {

                $WPFRemoteTxTB.Visibility = "Visible"
                $WPFRemoteComputerTxT.Visibility = "Visible"

            }

        })
    
    $WPFRetrieveProfilesBtN.Add_Click({ 

    

    
        
            if ($WPFRemoteComputerTxT.text -gt 1 -eq $true) {

                if (Test-Connection -computername $WPFRemoteComputerTxT.text -Quiet -Count 1) {
                    $NetTest = 'Pass'    
                }
                else {
                    $NetTest = 'Failed'
                }
         
                if ($NetTest -eq 'Failed') {
            
                    $msgBoxInput = [System.Windows.MessageBox]::Show('Cannot reach host machine, please test the network connection and try again.', 'User Profile Removal Script', 'Ok')
                }

            }
    
       
            
    

    
    
            if ($WPFRemoteComputerTxT.text -gt 1 -eq $True -and $NetTest -eq 'pass' ) {


     

                Invoke-Command -ComputerName $WPFRemoteComputerTxT.text -ScriptBlock {
        
                
                    Install-PackageProvider -Name nuget -Force
                
                    If (-not(Get-InstalledModule Userprofile -ErrorAction silentlycontinue)) {
                        Install-Module Userprofile -Confirm:$False -Force -Verbose

                    }

              
            

                }
            
                if ($WPFAdminRaDBtN.IsChecked -eq $True) {
                    $Profiles = invoke-command -ComputerName $WPFRemoteComputerTxT.Text -ScriptBlock {

                        Get-UserProfile | Sort LocalPath | Where-Object { ($_.LocalPath -match 'users') } -Verbose
        
                        $Profiles.localpath   | ForEach-Object { $WPFlistbox.Items.Add($_) } -Verbose
                
                    }
                }
                else {
                    $Profiles = invoke-command -ComputerName $WPFRemoteComputerTxT.Text -ScriptBlock {

                        Get-UserProfile | Sort LocalPath | Where-Object { ($_.LocalPath -match 'users') -and ($_.LocalPath -notmatch 'cov') } -Verbose
            
                        $Profiles.localpath   | ForEach-Object { $WPFlistbox.Items.Add($_) } -Verbose
                    
                    }
                }

            }
        
            $Profiles.localpath   | ForEach-Object { $WPFlistbox.Items.Add($_) }


            if ($WPFRemoteComputerTxT.text -gt 1 -eq $False  ) {

                $Profiles = Get-UserProfile | Sort LocalPath | Where-Object { ($_.LocalPath -match 'users') -and ($_.LocalPath -notmatch 'cov') } -Verbose
                $Profiles.localpath   | ForEach-Object { $WPFlistbox.Items.Add($_) } -Verbose -ErrorAction SilentlyContinue

            }

        })
    #Submit Button, removes any users in the designated removal column.

    $WPFSubmitBtN.Add_Click({

            if ($WPFRemoteComputerTxT.text -gt 1 -eq $False) {

                $test = $WPFListbox.Items
                $test.Remove($null)

                try {
            
                    Remove-UserProfile -LocalPath $test -Confirm:$False -ErrorAction Stop

            
                }
                catch {

                    $LocalError = $_
                }
                finally {

                    if ($LocalError -match 'The process cannot access the file because it is being used by another process.') {
                
                        $msgBoxInput = [System.Windows.MessageBox]::Show('The profile you are trying to remove is still currently logged in, please reboot the machine and try again.', 'User Profile Removal Script', 'Ok')
                    }
                    elseif ($LocalError -match 'The process cannot access the file because it is being used by another process.' -eq $False) {
                        $msgBoxInput2 = [System.Windows.MessageBox]::Show('User profiles have successfully been removed', 'User Profile Removal Script', 'Ok')

                        $WPFlistBox.items.Clear()
                        $WPFlistBoxCopy.items.Clear()
                        $WPFRemoteComputerTxT.Clear()
                        $WPFRemoteRaDBtN.IsChecked = $false
                        $WPFRemoteTxTB.Visibility = "Hidden"
                        $WPFRemoteComputerTxT.Visibility = "Hidden"

            
                    }
                



                }
         



            }



            if ($wpflistBox.Items.count -gt 0 -eq $true -and $WPFRemoteComputerTxT.text -gt 1 -eq $True) {

       
                $test = $WPFListbox.Items

                $Tanner = Invoke-Command -ComputerName $WPFRemoteComputerTxT.text -ScriptBlock {
            
                    try {
                        Remove-UserProfile -LocalPath $using:test -Confirm:$false -ErrorAction 1
                        $WPFlistBox.items.clear()
                        $msgBoxInput = [System.Windows.MessageBox]::Show('User profiles have been removed successfully', 'User Profile Removal Script', 'Ok')


                
                    }
                    catch {
                        return $_
                    }

           


            
        
                }

      
            

                if ($Tanner -match 'The process cannot access the file because it is being used by another process.') {

                    $msgBoxInput = [System.Windows.MessageBox]::Show('The profile you are trying to remove is still currently logged in, please reboot the machine and try again.', 'User Profile Removal Script', 'Ok')

                }
                
             

                if ($msgBoxInput.value__ -eq 1) {

                    $WPFlistBox.items.Clear()

    
                }

            
            
            
                if ($Tanner -match 'The process cannot access the file because it is being used by another process.' -eq $False) {

                    $msgBoxInput2 = [System.Windows.MessageBox]::Show('User profiles have successfully been removed', 'User Profile Removal Script', 'Ok')

                    $WPFlistBox.items.Clear()
                    $WPFlistBoxCopy.items.Clear()
                    $WPFRemoteComputerTxT.Clear()
                    $WPFRemoteRaDBtN.IsChecked = $false
                    $WPFRemoteTxTB.Visibility = "Hidden"
                    $WPFRemoteComputerTxT.Visibility = "Hidden"
            
                }
            
          



            }

          
        


    
        })





    #Add button, adds items from the left side listbox to the right.
    $WPFAddBtN.Add_Click({

            if ($WPFlistbox.selecteditem -ne $null) {
    
                while ($wpflistbox.SelectedItems.Count -gt 0) {
                    $wpflistBoxcopy.Items.Add($wpflistbox.SelectedItem)
                    $wpflistbox.items.remove($wpflistbox.SelectedItem)
                }

            }
        })


    #Remove Button, takes items from the left side listbox and places them back in the right.
    $WPFRemoveBtN.Add_Click({

            if ($WPFlistboxcopy.selecteditem -ne $null) {
        
                while ($wpflistboxcopy.SelectedItems.Count -gt 0) {
                    $wpflistBox.Items.Add($wpflistboxcopy.SelectedItem)
                    $wpflistboxcopy.items.remove($wpflistboxcopy.SelectedItem)
                }
    
            }



        })

    #Radio button, makes the Remote computer text box and text box visible
    $WPFRemoteRaDBtN.Add_Click({

            $WPFRemoteTxTB.Visibility = "Visible"
            $WPFRemoteComputerTxT.Visibility = "Visible"
        })


  
    $Form.ShowDialog() | out-null

}