PowerShell Logo Small

about_Classes



This is the built-in help made by Microsoft for the document 'about_Classes', in PowerShell version 4 - as retrieved from Windows version 'Microsoft Windows 8.1 Enterprise' PowerShell help files on 2016-06-24.

For PowerShell version 3 and up, where you have Update-Help, this command was run just before creating the web pages from the help files.

Search powershellhelp.space

TOPIC
about_Classes

SHORT DESCRIPTION
Describes how you can use classes to develop in Windows PowerShell

LONG DESCRIPTION
Starting in Windows PowerShell 5.0, Windows PowerShell adds language
for defining classes and other user-defined types, by using formal syntax
and semantics that are similar to other object-oriented programming
languages. The goal is to enable developers and IT professionals to
embrace Windows PowerShell for a wider range of use cases, simplify
development of Windows PowerShell artifacts--such as Windows PowerShell
Desired State Configuration (DSC) resources--and accelerate coverage
of management surfaces.


SUPPORTED SCENARIOS
-- Define DSC resources and their associated types by using the
Windows PowerShell language.
-- Define custom types in Windows PowerShell by using familiar object-
oriented programming constructs, such as classes, properties, methods,
inheritance, etc.
-- Debug types by using the Windows PowerShell language.
-- Generate and handle exceptions by using formal mechanisms, and at the
right level.


DEFINE DSC RESOURCES WITH CLASSES
Apart from syntax changes, the major differences between a class-defined
DSC resource and a cmdlet DSC resource provider are the following.

-- A MOF file is not required.
-- A DSCResource subfolder in the module folder is not required.
-- A Windows PowerShell module file can contain multiple DSC resource
classes.

The following is an example of a class-defined DSC resource provider;
this is saved as a module, MyDSCResource.psm1. Note that you must always
include a key property in a class-defined DSC resource provider.

# This module defines a class for a DSC "FileResource" provider.

enum Ensure
{
Absent
Present
}

<# This resource manages the file in a specific path.
[DscResource()] indicates the class is a DSC resource
#>
[DscResource()]
class FileResource
{
<# This is a key property
[DscResourceKey()] also means the property is required.
#>
[DscResourceKey()][string]$Path
[Ensure] $Ensure

<#
[DscResourceMandatory()] means the property is required.
#>
[DscResourceMandatory()]
[string] $SourcePath
#>
<#
This method replaces the Set-TargetResource DSC script function.
It sets the resource to the desired state. The DSC engine sets
all of the properties from the configuration.

[DscResourceKey()] or [DscResourceMandatory()] are guaranteed to
be set, other properties may not be set if the configuration did
not specify values.
#>
[void] Set()
{
if($ensure -eq [Ensure]::Present)
{
if (!(Test-Path $Path))
{
$err = Copy-Item $SourcePath $Path
if ($err)
{
Write-Verbose ("(ERROR) Failed to copy file from '{0}' to '{1}'",
$SourcePath, $Path)
throw $err
}
}
}
else
{
if (Test-Path $Path)
{
del $Path
}
}
}

<#
This method replaces the Test-TargetResource function.
It should return True or False, showing whether the resource is in a desired
state.
The DSC engine sets all of the properties from the configuration.
Properties with [DscResourceKey()] or [DscResourceMandatory()] are
guaranteed to be set, other properties may not be set if the
configuration did not specify values.
#>
[bool] Test()
{
if($ensure -eq [Ensure]::Present)
{
return Test-Path $Path
}
else
{
return !(Test-Path $Path)
}
}



<#
This method replaces the Get-TargetResource function.
The DSC engine sets all of the properties from the configuration.
Properties with [DscResourceKey()] or [DscResourceMandatory()] are
guaranteed to be set; other properties may not be set if the
configuration did not specify values.
The implementation should use the keys to find appropriate resources.
This method returns an instance of this class with the updated key properties.
#>
[FileResource] Get()
{
$file = Get-item $Path

return $this
}

After creating the class-defined DSC resource provider, and saving it as a
module, create a module manifest for the module. In this example, the following
module manifest is saved as MyDscResource.psd1.

@{

# Script module or binary module file associated with this manifest.
RootModule = 'MyDscResource.psm1'

# Version number of this module.
ModuleVersion = '1.0'

# ID used to uniquely identify this module
GUID = 'GUID'

# Author of this module
Author = 'Author name'

# Company or vendor of this module
CompanyName = 'Microsoft

# Copyright statement for this module
Copyright = '(c) 2014 Microsoft. All rights reserved.'

# Description of the functionality provided by this module
# Description = 'DSC resource provider for FileResource.'

# Minimum version of the Windows PowerShell engine required by this module
# PowerShellVersion = ''

# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''

}

Deploy the new DSC resource provider by creating a MyDscResource folder for
it in $pshome\Modules or $env:SystemDrive\Program Files\WindowsPowerShell\Modules.
You do not need to create a DSCResource subfolder. Copy the module and module
manifest files (MyDscResource.psm1 and MyDscResource.psd1) to the MyDscResource
folder.

From this point, you create and run a configuration script as you would with
any DSC resource. The following is a configuration that references the
MyDSCResource module. Save this as a script, MyResource.ps1.


CONFIGURATION TEST
{
Import-DSCResource -module MyDscResource
FileResource file
{
Path = "C:\test\test.txt"
SourcePath = "c:\test.txt"
Ensure = "Present"
}
}
Test


Run this as you would any DSC configuration script. To start the configuration,
in an elevated Windows PowerShell console, run the following.

PS C:\test> .\MyResource.ps1

DEFINING CUSTOM TYPES IN WINDOWS POWERSHELL
Windows PowerShell 5.0 introduces the following language elements.

Class keyword
Defines a new class. This is a true .NET Framework type.
Class members are public, but only public within the module scope.
You can't refer to the type name as a string (for example, New-Object
doesn't work), and in this release, you can't use a type literal (for
example, [MyClass]) outside the script/module file in which the class
is defined.
class MyClass
{
}

Enum keyword and enumerations
Support for the enum keyword has been added; this is a breaking change.
The enum delimiter is currently a newline. A workaround for those who
are already using enum is to insert an ampersand (&) before the word.
Current limitations: you cannot define an enumerator in terms of itself,
but you can initialize enum in terms of another enum, as shown in the
following example. The base type cannot currently be specified; it is always
[int].
enum Color2
{
Yellow = [Color]::Blue
}
An enumerator value must be a parse time constant; you cannot set it to
the result of an invoked command.
enum MyEnum
{
Enum1
Enum2
Enum3 = 42
Enum4 = [int]::MaxValue
}
Enums support arithmetic operations, as shown in the following example.
enum SomeEnum { Max = 42 }
enum OtherEnum { Max = [SomeEnum]::Max + 1 }



Import-DscResource
Import-DscResource is now a true dynamic keyword. Windows PowerShell
parses the specified module’s root module, searching for classes that
contain the DscResource attribute.

Properties
A new field, ImplementingAssembly, has been added to ModuleInfo. It
is set to the dynamic assembly created for a script module if the script
defines classes, or the loaded assembly for binary modules. It is not
set when ModuleType = Manifest.

Reflection on the ImplementingAssembly field discovers resources in a
module. This means you can discover resources written in either
Windows PowerShell or other managed languages.

Fields with initializers:
[int] $i = 5
Static is supported; it works like an attribute, as do the type constraints,
so it can be specified in any order.
static [int] $count = 0
A type is optional.
$s = "hello"

All members are public. Properties require either a newline or semicolon.
If no object type is specified, the property type is “object.”

Constructors and instantiation
Windows PowerShell classes can have constructors; they have the same
name as their class. Constructors can be overloaded. Static constructors
are supported. Properties with initialization expressions are initialized
before running any code in a constructor. Static properties are initialized
before the body of a static constructor, and instance properties are
initialized before the body of the non-static constructor. Currently, there
is no syntax for calling a constructor from another constructor (like the
C# syntax ": this()"). The workaround is to define a common Init method.

The following are ways of instantiating classes in this release.
# Instantiating by using the default constructor. Note that New-Object is not
supported in this release.
$a = [MyClass]::new()

# Calling a constructor with a parameter
$b = [MyClass]::new(42)

# Passing an array to a constructor with multiple parameters
$c = [MyClass]::new(@(42,43,44), "Hello")

In this release, New-Object does not work with classes defined in Windows
PowerShell. Also for this release, the type name is only visible lexically,
meaning it is not visible outside of the module or script that defines the
class. Functions can return instances of a class defined in Windows
PowerShell, and instances work well outside of the module or script.

Get-Member -Static lists constructors, so you can view overloads like
any other method. The performance of this syntax is also considerably
faster than New-Object.

The pseudo-static method named new works with .Net types, as shown in
the following example.

[hashtable]::new()

You can now see constructor overloads with Get-Member, or as shown in
this example:

PS> [hashtable]::new
OverloadDefinitions
-------------------
hashtable new()
hashtable new(int capacity)
hashtable new(int capacity, float loadFactor)

Methods
A Windows PowerShell class method is implemented as a ScriptBlock that
has only an end block. All methods are public. The following shows an
example of defining a method named DoSomething.
class MyClass
{
DoSomething($x)
{
$this._doSomething($x) # method syntax
}
private _doSomething($a) {}
}

Method invocation:
$b = [MyClass]::new()
$b.DoSomething(42)

Overloaded methods--that is, those that are named the same as an
existing method, but differentiated by their specified values--are also supported.

Invocation
See “Method invocation” in this list.

Attributes
Three new attributes, DscResource, DscResourceKey, and DscResourceMandatory,
have been added.

Return types
Return type is a contract; the return value is converted to the expected
type. If no return type is specified, the return type is void. There
is no streaming of objects; objects cannot be written to the pipeline
either intentionally or by accident.

Lexical scoping of variables
The following shows an example of how lexical scoping works in this
release.
$d = 42 # Script scope

function bar
{
$d = 0 # Function scope
[MyClass]::DoSomething()
}

class MyClass
{
static [object] DoSomething()
{
return $d # error, not found dynamically
return $script:d # no error

$d = $script:d
return $d # no error, found lexically
}
}

$v = bar
$v -eq $d # true


EXAMPLE
The following example creates several new, custom classes to implement
an HTML dynamic stylesheet language (DSL). Then, the example adds helper
functions to create specific element types as part of the element class,
such as heading styles and tables, because types cannot be used outside
the scope of a module.

# Classes that define the structure of the document
#
class Html
{
[string] $docType
[HtmlHead] $Head
[Element[]] $Body

[string] Render()
{
$text = "<html>`n<head>`n"
$text += $Head
$text += "`n</head>`n<body>`n"
$text += $Body -join "`n" # Render all of the body elements
$text += "</body>`n</html>"
return $text
}
[string] ToString() { return $this.Render() }
}

class HtmlHead
{
$Title
$Base
$Link
$Style
$Meta
$Script
[string] Render() { return "<title>$Title</title>" }
[string] ToString() { return $this.Render() }
}

class Element
{
[string] $Tag
[string] $Text
[hashtable] $Attributes
[string] Render() {
$attributesText= ""
if ($Attributes)
{
foreach ($attr in $Attributes.Keys)
{
$attributesText = " $attr=`"$($Attributes[$attr])`""
}
}

return "<${tag}${attributesText}>$text</$tag>`n"
}
[string] ToString() { return $this.Render() }
}

#
# Helper functions for creating specific element types on top of the classes.
# These are required because types aren’t visible outside of the module.
#
function H1 { [Element] @{ Tag = "H1" ; Text = $args.foreach{$_} -join " " }}
function H2 { [Element] @{ Tag = "H2" ; Text = $args.foreach{$_} -join " " }}
function H3 { [Element] @{ Tag = "H3" ; Text = $args.foreach{$_} -join " " }}
function P { [Element] @{ Tag = "P" ; Text = $args.foreach{$_} -join " " }}
function B { [Element] @{ Tag = "B" ; Text = $args.foreach{$_} -join " " }}
function I { [Element] @{ Tag = "I" ; Text = $args.foreach{$_} -join " " }}
function HREF
{
param (
$Name,
$Link
)

return [Element] @{
Tag = "A"
Attributes = @{ HREF = $link }
Text = $name
}
}
function Table
{
param (
[Parameter(Mandatory)]
[object[]]
$Data,
[Parameter()]
[string[]]
$Properties = "*",
[Parameter()]
[hashtable]
$Attributes = @{ border=2; cellpadding=2; cellspacing=2 }
)

$bodyText = ""
# Add the header tags
$bodyText += $Properties.foreach{TH $_}
# Add the rows
$bodyText += foreach ($row in $Data)
{
TR (-join $Properties.Foreach{ TD ($row.$_) } )
}


$table = [Element] @{
Tag = "Table"
Attributes = $Attributes
Text = $bodyText
}
$table
}
function TH { ([Element] @{ Tag = "TH" ; Text = $args.foreach{$_} -join " " }) }
function TR { ([Element] @{ Tag = "TR" ; Text = $args.foreach{$_} -join " " }) }
function TD { ([Element] @{ Tag = "TD" ; Text = $args.foreach{$_} -join " " }) }

function Style
{
return [Element] @{
Tag = "style"
Text = "$args"
}
}

# Takes a hash table, casts it to and HTML document
# and then returns the resulting type.
#
function Html ([HTML] $doc) { return $doc }

SEE ALSO
about_DesiredStateConfiguration
about_Language_Keywords
about_Methods