Sunday, January 19, 2025

About PowerShellGet

 

What is PowerShellGet?

  • The PowerShellGet module includes cmdlets for accessing and publishing items in the PowerShell Gallery.

  • When you use the cmdlets in the PowerShellGet module for the first time, you're prompted to install the NuGet provider. NuGet is a package manager that can obtain and install packages on Windows. The cmdlets in the PowerShellGet module use the functionality in NuGet to interact with the PowerShell Gallery.

The following table lists the two cmdlets used most often to find content in the PowerShell Gallery.

Table 1: Cmdlets used to find content in the PowerShell Gallery

Cmdlet

Description

Find-Module

Use this cmdlet to search for Windows PowerShell modules in the PowerShell Gallery. The simplest usage conducts searches based on the module name, but you can also search based on the command name, version, DscResource, and RoleCapability.

Find-Script

Use this cmdlet to search for Windows PowerShell scripts in the PowerShell Gallery. The simplest usage conducts searches based on the script name, but you can also search based on the version.

 

Private PowerShell Gallery

You can implement a private PowerShell gallery for your organization by creating your own NuGet feed. You can create a NuGet feed with a file share or a web-based application. When you have a private PowerShell gallery, you must register the NuGet feed by using the Register-PSRepository cmdlet and specifying the source location. After the repository is registered, users can search it, just like the PowerShell Gallery.

 

Additional reading: For more information about creating a NuGet feed, refer to Hosting your own NuGet feeds.


Saturday, January 18, 2025

Exploring Modules and Commands

Introduction

PowerShell is a powerful task automation and configuration management framework from Microsoft, consisting of a command-line shell and associated scripting language. For beginners, navigating PowerShell's vast landscape of modules, commands, and cmdlets can be overwhelming. This guide aims to simplify the process, providing a starting point for exploration and familiarization with fundamental concepts.

Understanding PowerShell Modules

Modules are self-contained units of PowerShell code that can include cmdlets, providers, functions, aliases, and variables. They provide a way to organize and distribute PowerShell functionality.

Getting Started: Finding and Installing Modules

  1. Find Available Modules: Use the `Get-Module -ListAvailable` cmdlet to see a list of modules already installed on your system.

  2. Install New Modules: Use the `Install-Module` cmdlet to install new modules from the PowerShell Gallery or other sources.

Exploring Module Contents

Once you've found or installed a module, you can explore its contents to see what commands, cmdlets, and other elements it contains.


  1. Get Command: Use the `Get-Command -Module <ModuleName>` cmdlet to see a list of all commands (including cmdlets, functions, and aliases) within a specific module.

  1. Get-Help: Use the `Get-Help <CommandName>` cmdlet to get detailed help and information about a specific command, including its syntax, parameters, and examples.

Example: Exploring the `ActiveDirectory` Module

Let's say you're interested in working with Active Directory using PowerShell. Here's how you might explore the `ActiveDirectory` module:


  1. Check if Installed: Use `Get-Module -ListAvailable | Where-Object {$_.Name -eq 'ActiveDirectory'}` to see if the module is already installed.

  2. Install if Needed: If not installed, use `Install-Module -Name ActiveDirectory` to install it.

  3. List Commands: Use `Get-Command -Module ActiveDirectory` to see a list of all commands within the module.

  4. Get Help for a Command: Use `Get-Help Get-ADUser` (for example) to get detailed help about the `Get-ADUser` cmdlet.

Key PowerShell Concepts

As you explore modules and commands, keep these fundamental PowerShell concepts in mind:


  • Cmdlets: These are the core commands in PowerShell, following a Verb-Noun naming convention (e.g., `Get-ChildItem`, `Set-Location`).  The words “Commands” and “cmdlets” are sometimes used interchangeably, but a cmdlet is a compiled script ready for use in a session (if imported) and a command, is a function call with the Verb-Noun pattern, like “Get-Process”.

  • Objects: PowerShell works with objects, which have properties (characteristics) and methods (actions).  

    • Powershell commands ALWAYS produce objects as output.  Even the use of ‘Out-String’ sends a string object to the console output.  This highlight is critical to understanding what PowerShell does underneath the hood.  You can use the -Verbose command to see what some of the internals are doing, but the concept of returned objects is applied in all cases.

  • Pipelines: You can use the pipe symbol (`|`) to chain cmdlets together, passing the output of one cmdlet as input to the next.  

    • Powershell objects returned by the pipeline are like excel rows and columns.  An object is like a row in the sheet, and each column in the sheet is essentially a property of the object.  By referring to the property names, you can access their contents.  Structured data output, that is, objects, are at the deep core of what Powershell is.

  • Providers: These allow you to access data stores (like the file system, certificates or the registry) as if they were drives.  Since the PSProviders are built-in, we can use the Get-ChildItem, for example, on any of the providers using the -Path parameter as shown:

    • File System:  Get-ChildItem -Path C:\temp\ -Recurse

    • Registry (Current User Hive):  Get-ChildItem -Path HKCU:\Software\

    • Certificates:  Get-ChildItem -Path Cert:\LocalMachine\My 

Conclusion

By exploring PowerShell modules and commands, you can gradually build your understanding of this powerful tool and its capabilities. Remember to use the `Get-Command` and `Get-Help` cmdlets to discover and learn about new cmdlets, and don't be afraid to experiment and try things out.


Installation differences in PowerShell Versions

 

Getting Versioning Clarity

PowerShell and Windows PowerShell are separately installed and you can run supported commands using either environment.

There are two versions of Powershell:

  1. Windows PowerShell - Windows PowerShell is available exclusively for the Windows OS.   All versions of Windows PowerShell up to and including 5.1, which is the version available with Windows 10, are integrated with a Windows OS.

  2. PowerShell - PowerShell is shipped, installed, and configured separately from Windows PowerShell.  First released as PowerShell Core 6.0 in 2018, it was the first version that offered multi-platform support, extending its availability to macOS and Linux operating systems.  However, PowerShell 7 is the defacto for cross-platform scripting in PowerShell with v6 retired.

 

Installation differences in PowerShell Versions

Installing the latest version of PowerShell results in the following when compared to Windows PowerShell:

  • Separate installation path and executable name.

    • Windows PowerShell 5.1 is installed in the $env:WINDIR\System32\WindowsPowerShell\v1.0 location.

    • PowerShell 7 is installed in the $env:ProgramFiles\PowerShell\7 location.  The new location is added to your PATH, which allows you to run both Windows PowerShell 5.1 and PowerShell 7.

    • In Windows PowerShell, the PowerShell executable is named powershell.exe.

    • In version 6 and newer, the executable is named pwsh.exe. The new name makes it easy to support side-by-side execution of both versions.

  • Separate PSModulePath. By default, Windows PowerShell and PowerShell 7 store modules in different locations.  PowerShell 7 combines those locations in the $Env:PSModulePath environment variable.  

    • When you import a module by name, PowerShell checks the location that $Env:PSModulePath specifies.  This feature allows PowerShell 7 to load both Core and Desktop modules.

  • Separate profiles for each version. A PowerShell profile is a script that runs when PowerShell starts.  This script customizes the PowerShell environment by adding commands, aliases, functions, variables, modules, and PowerShell drives.

    • In Windows PowerShell 5.1, the profile's location is $HOME\Documents\WindowsPowerShell.

    • In PowerShell 7, the profile's location is $HOME\Documents\PowerShell.

  • Separate event logs. Windows PowerShell and PowerShell 7 log events to separate Windows event logs (if using a Windows Server or PC).

 

When you're reviewing a PowerShell session, it's important to determine which version you're using.  To determine the current version, enter $PSVersionTable in the PowerShell console, and then select Enter.  PowerShell displays the version numbers for various components, including the main PowerShell version number.

 

PowerShell and Bit-ness

  • On 64-bit operating systems, the PowerShell host applications are available in both 64-bit (x64) and 32-bit (x86) versions.

  • On 32-bit operating systems, PowerShell’s host applications are available only in 32-bit versions.  When working with Windows PowerShell, you'll notice that the icons and window title bars don't have the (x86) designation.  Instead, they display simply as Windows PowerShell and Windows PowerShell ISE in the Start menu.

  • If you intend to use PowerShell to perform administrative tasks on computers that have User Account Control (UAC) enabled, you might have to take an extra step to run PowerShell cmdlets with full administrative credentials.  To do this, right-click or activate the context menu for the application icon, and then select Run as Administrator. When you're running PowerShell with administrative credentials, the host application’s window title bar will include the Administrator prefix


Sunday, January 12, 2025

WPF GUI Using C# or PowerShell

C# and WPF (XAML) GUI


For displaying the output of Get-Process | Format-Table | Out-String in a WPF window, you have a few good options, each with its own strengths:

1. TextBox:

  • Pros: Simple to use, readily available. Handles scrolling automatically.
  • Cons: Limited formatting options. Might not preserve the table structure perfectly, especially if it involves complex formatting.

2. RichTextBox:

  • Pros: Offers more control over formatting. You can potentially retain some of the table-like structure by using tabs or other formatting.
  • Cons: Can be slightly more complex to work with than a TextBox.

3. DataGrid:

  • Pros: Excellent for displaying tabular data. If you can convert the output of Get-Process into objects, DataGrid will present them clearly in a structured grid.
  • Cons: Requires restructuring the PowerShell output into objects that the DataGrid can bind to.

4. ListView with GridView:

  • Pros: Provides a flexible way to display data in a grid-like format with customizable columns.
  • Cons: Like the DataGrid, it requires processing the output of Get-Process to fit the ListView structure.

Recommendation:

If you need to preserve the exact table formatting from Format-Table, RichTextBox might be the best choice. However, if you prioritize clear, structured presentation and are willing to convert the PowerShell output into objects, DataGrid is generally the most suitable option for displaying tabular data in WPF.

Example using DataGrid:

C#

using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Management.Automation;
using System.Windows;

public partial class MainWindow : Window
{
   
public ObservableCollection<ProcessInfo> Processes { get; set; }

   
public MainWindow()
   {
       InitializeComponent();
       Processes =
new ObservableCollection<ProcessInfo>();
       DataContext =
this;
       LoadProcesses();
   }

   
private void LoadProcesses()
   {
       
using (PowerShell ps = PowerShell.Create())
       {
           ps.AddCommand(
"Get-Process");
           
foreach (PSObject result in ps.Invoke())
           {
               Processes.Add(
new ProcessInfo
               {
                   ProcessName = result.Properties[
"ProcessName"].Value.ToString(),
                   Id =
int.Parse(result.Properties["Id"].Value.ToString()),
                   
// Add other properties as needed
               });
           }
       }
   }
}

public class ProcessInfo
{
   
public string ProcessName { get; set; }
   
public int Id { get; set; }
   
// Add other properties as needed
}


XAML:

<Window ... >
   
<Grid>
       
<DataGrid ItemsSource="{Binding Processes}" AutoGenerateColumns="True" />
   
</Grid>
</Window>


This example demonstrates how to use DataGrid to display process information. You'll need to adjust the properties in ProcessInfo to match the ones you want to show from Get-Process.

PowerShell and XAML Script


So, the first example was using C# as a back-end language to invoke PowerShell and pass the “Get-Process” command via a string in ps.AddCommand property of the PowerShell object.  But, we can also use PowerShell as the language to load the XAML in a PowerShell session and iterate and create PSCustomObject’s for each invocation that finds each process one by one.  

Add-Type -AssemblyName PresentationFramework

# Create the XAML for the window
$xaml = @'
<Window
   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
   Title="Process Viewer" Height="300" Width="500">
   <Grid>
       <DataGrid x:Name="dataGrid" AutoGenerateColumns="True" />
   </Grid>
</Window>
'@


# Create the WPF window

$window = [Windows.Markup.XamlReader]::Parse($xaml)

# Function to get process information
function Get-ProcessInfo {
   
Get-Process | ForEach-Object {
       [PSCustomObject]@{
           ProcessName =
$_.ProcessName
           Id           =
$_.Id
           
# Add other properties as needed
       }
   }
}

# Get process data
$processes = Get-ProcessInfo

# Bind the data to the DataGrid
$window.FindName("dataGrid").ItemsSource = $processes

# Show the window
$window.ShowDialog()

Step Details:

  1. Add WPF Assembly: Add-Type -AssemblyName PresentationFramework imports the necessary WPF libraries.
  2. Define XAML: The $xaml variable holds the XAML code for a simple window with a DataGrid.
  3. Create Window: [Windows.Markup.XamlReader]::Parse($xaml) creates the WPF window object from the XAML string.
  4. Get-ProcessInfo Function: This function fetches process information using Get-Process and formats it into custom objects with properties like ProcessName and Id. You can add more properties as needed.
  5. Bind Data: $window.FindName("dataGrid").ItemsSource = $processes finds the DataGrid in the window and sets its ItemsSource to the $processes collection, populating the grid.
  6. Show Window: $window.ShowDialog() displays the WPF window.

To run this code:

  1. Save it as a .ps1 file (e.g., process_viewer.ps1).
  2. Run the script from PowerShell: .\process_viewer.ps1

This will open a WPF window with a DataGrid displaying the process information.

This approach keeps the core logic in PowerShell, leveraging its capabilities for data retrieval and manipulation, while using WPF for the user interface.