Reader small image

You're reading from  Mastering PowerShell Scripting - Fourth Edition

Product typeBook
Published inJun 2021
PublisherPackt
ISBN-139781800206540
Edition4th Edition
Right arrow
Author (1)
Chris Dent
Chris Dent
author image
Chris Dent

Chris Dent is an automation specialist with deep expertise in the PowerShell language. Chris is often found answering questions about PowerShell in both the UK and virtual PowerShell user groups. Chris has been developing in PowerShell since 2007 and has released several modules over the years.
Read more about Chris Dent

Right arrow

Working with .NET

Microsoft .NET is an extensive library of APIs (Application Program Interfaces, or pre-created code) that can be used by developers when writing applications, or scripters when writing scripts. Microsoft has created several different versions of .NET over the years starting with .NET Framework 1.0 released in 2002. .NET Framework is limited to the Windows operating system.

Windows PowerShell is built using .NET Framework. The .NET Framework version depends on the local installation and the PowerShell version. PowerShell 5.1 was built using .NET 4.5 and can make use of .NET 4.8 if it is installed: https://docs.microsoft.com/dotnet/api/?view=netframework-4.8.

In 2016, Microsoft released .NET Core, a release of .NET that could be run across different platforms, including Windows, Linux distributions, and macOS.

PowerShell 6 and PowerShell 7.0 were built using .NET Core, that is, .NET Core 3.1 for PowerShell 7.0. PowerShell 7.0 can therefore make use of many...

Assemblies

An assembly is a collection of types and any other supporting resources. .NET objects are implemented within assemblies. An assembly may be static (based on a file) or dynamic (created in memory).

The assembly type load locations can be seen by exploring the Assembly property of the type. For example, the String type is loaded from System.Private.CoreLib.dll in PowerShell 7:

PS> [System.String].Assembly.Location
C:\Program Files\PowerShell\7\System.Private.CoreLib.dll

In PowerShell 7, the assemblies that are loaded by default or those that can be loaded by name are in the $PSHome directory.

You can view the list of currently loaded assemblies in a PowerShell session using the following statement:

[System.AppDomain]::CurrentDomain.GetAssemblies() 

The list can be quite extensive and can grow as different modules (which might depend on other .NET types) are loaded. The first few lines are shown here:

GAC    Version     Location
---    ---...

Types

A type is used to represent the generalized functionality of an object. This description is vague, but a .NET type can be used to describe anything; it is hard to be more specific. To use this book as an example, it could have several types, including the following:

  • PowerShellBook
  • TextBook
  • Book

Each of these types describes how an object can behave. The type does not describe how this book came to be, or whether it will do anything (on its own) to help create one.

In PowerShell, types are written between square brackets. The [System.AppDomain] and [System.Management.Automation.PowerShell] statements, used when discussing previous assemblies, are types.

The type of an object can be revealed by the Get-Member command (the following output is truncated):

PS> 1 | Get-Member
   TypeName: System.Int32
Name        MemberType Definition
----        ---------- ----------
CompareTo   Method     int CompareTo(System.Object value), int ......

Enumerations

An enumeration is a specialized type that is used to express a list of constants. Enumerations are used throughout .NET and PowerShell.

PowerShell itself makes use of enumerations for many purposes. For example, the possible values for the $VerbosePreference variable are described in an enumeration:

PS> $VerbosePreference.GetType()
IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     ActionPreference                         System.Enum

Notice that the BaseType is System.Enum, indicating that this type is an enumeration.

The possible values for an enumeration can be listed in several different ways. The most convenient of these is to use the GetEnumValues() method on the enumeration type:

PS> $VerbosePreference.GetType().GetEnumValues()
SilentlyContinue
Stop
Continue
Inquire
Ignore
Suspend
Break

Enumerations are relatively simple types. They...

Classes

A class is a set of instructions that dictates how a specific instance of an object behaves, including how it can be created and what it can do. A class is, in a sense, a recipe.

In the case of this book, a class might include details of authoring, editorial processes, and publication steps. These steps are, hopefully, invisible to anyone reading this book; they are part of the internal implementation of the class. Following these steps will produce an instance of the PowerShellBook object.

Once a class has been compiled, it is used as a type. The members of the class are used to interact with the object. Members are explored later in this chapter.

Classes (and types) are arranged and categorized into namespaces.

Namespaces

A namespace is used to organize types into a hierarchy, grouping types with related functionality together. A namespace can be considered like a folder in a file system.

PowerShell is for the most part implemented in the System.Management.Automation namespace. This namespace has associated documentation: https://docs.microsoft.com/dotnet/api/system.management.automation?view=powershellsdk-7.0.0.

Similarly, types used to work with the filesystem are grouped together in the System.IO namespace: https://docs.microsoft.com/dotnet/api/system.io.

For the following given type name, the namespace is everything before the final label. The namespace value is accessible as a property of the type:

PS> [System.IO.File].Namespace
System.IO

In PowerShell, the System namespace is implicit. The System.AppDomain type was used at the start of the chapter to show which assemblies PowerShell is currently using. This can be shortened to:

[AppDomain]::CurrentDomain...

The using keyword

The using keyword simplifies the use of namespaces and can be used to load assemblies or PowerShell modules. The using keyword was introduced with PowerShell 5.0.

You can use the using keyword in a script, a module, or the console. In a script, the using keyword can only be preceded by comments.

The using module statement is used to access PowerShell classes created within a PowerShell module. The using module statement is explored in Chapter 19, Classes and Enumerations.

In the context of working with .NET, namespaces and assemblies are of interest.

Using namespaces

The using namespace statement instructs PowerShell to look for any type names used in an additional namespace. For example, by default, attempting to use System.IO.File without a full name will result in an error:

PS> [File]
InvalidOperation: Unable to find type [File].

PowerShell looked for the type in the System namespace and did not find it.

If using namespace...

Type accelerators

A type accelerator is an alias for a type. At the beginning of this chapter, the System.Management.Automation.PowerShell type was used; this type has an accelerator available. The accelerator name is simply PowerShell. The accelerator allows the following to be used:

[PowerShell].Assembly 

Another commonly used example is the ADSI accelerator. This represents the System.DirectoryServices.DirectoryEntry type. This means that the following two commands are equivalent:

[System.DirectoryServices.DirectoryEntry]"WinNT://$env:COMPUTERNAME" 
[ADSI]"WinNT://$env:COMPUTERNAME"

The full type name behind a type accelerator can be seen using the FullName property:

PS> [ADSI].FullName
System.DirectoryServices.DirectoryEntry

PowerShell includes a lot of type accelerators; these accelerators are documented in about_Type_Accelerators:

Get-Help about_Type_Accelerators

Types have members; the members available depend on the...

Members

All types have members. Members represent data, or dictate the behavior of the object represented by a type.

In .NET, the members are described in the C Sharp (C#) programming guide on Microsoft Docs: https://docs.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/members.

PowerShell also adds members; these member types are also described on Microsoft Docs: https://docs.microsoft.com/dotnet/api/system.management.automation.psmembertypes.

This section focuses on a small number of members used when working with .NET types:

  • Constructors
  • Methods
  • Properties

The Event member is explored in Chapter 15, Asynchronous Processing.

The ScriptProperty and ScriptMethod property types are specific to PowerShell and may be added with the Add-Member command. These member types are outside of the scope of this chapter.

Constructors are one possible way of creating an instance of a type.

Constructors

A constructor is...

Reflection in PowerShell

Types, properties, and methods can be marked as internal or private. Internal types and members are only accessible by other types and members within the same assembly. Private members are only accessible within the same class or type. Collectively these can be described as non-public types and members.

Non-public types and members are accessible using what is known as Reflection. Microsoft Docs describes Reflection in the dynamic programming guide: https://docs.microsoft.com/dotnet/framework/reflection-and-codedom/reflection.

PowerShell can make use of Reflection to explore and use non-public types and members. Doing so introduces a risk; such types and members are not part of a public-supported API. As code is updated, these non-public types and members may disappear or change behavior. It is therefore not recommended to make code that is to be used in production dependent on a non-public implementation.

Even if it might not be supported, exploring...

Summary

Delving into .NET significantly increases the flexibility of PowerShell over using built-in commands and operators. .NET is made up of hundreds of classes and enumerations, many of which can be easily used in PowerShell.

.NET types are arranged in namespaces, grouping types with similar purposes together. For example, the System.Data.SqlClient namespace contains types for connecting to and querying Microsoft SQL Server instances.

The using keyword, introduced with PowerShell 5.1, allows types to be used by name only, instead of the full name that includes the namespace.

Type accelerators have been in PowerShell since its release. PowerShell provides many built-in type accelerators allowing types to be used by a short name. Examples include Xml for System.Xml.XmlDocument, and ADSI for System.DirectoryServices.DirectoryEntry.

Types in .NET have members including constructors, properties, and methods. These are used to hold information or enact change on an object...

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Mastering PowerShell Scripting - Fourth Edition
Published in: Jun 2021Publisher: PacktISBN-13: 9781800206540
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Chris Dent

Chris Dent is an automation specialist with deep expertise in the PowerShell language. Chris is often found answering questions about PowerShell in both the UK and virtual PowerShell user groups. Chris has been developing in PowerShell since 2007 and has released several modules over the years.
Read more about Chris Dent