Using .Net Objects in a Powershell Class (V5)

This is a major change made for clarity. I think I need to work on shaping my thoughts. Below is the exact code I'm having problems with. Short Description: I am trying to install a powershell class that will contain objects of different types for easy access. I have done this many times in C #, so I thought it would be pretty straight forward. The types [System.Printing] and WMI-Objects are required.

I initially tried to write the class directly in my Powershell profile for ease of use, but my profile does not load when it has class code. Saying that he cannot find a name like "System.Printing.PrintServer" or any other explicitly listed types. After that, I moved it to my own module, and then set my profile to import the module to open. However, even when saving in my own module, if I explicitly list the .Net Type for any of the properties, the whole module does not load. Regardless, I added or imported the / dll type. The specific problem area is: [String] $ Name [System.Printing.PrintServer] $ Server [System.Printing.PrintQueue] $ Queue [System.Printing.PrintTicket] $ tickets [System.Management.ManagementObject] $ apiece [BOOL] $ IsDefault

When I install this, all the “views” work, but then all my properties are of type _Object, which does not help. [String] $ Name $ Server $ Queue $ Tickets $ apiece $ IsDefault

Add-Type -AssemblyName System.Printing
Add-Type -AssemblyName ReachFramework
Class PrinterObject
{
    [string]$Name
    [System.Printing.PrintServer]$Server
    [System.Printing.PrintQueue]$Queue
    [System.Printing.PrintTicket]$Ticket
    [System.Management.ManagementObject]$Unit
    [bool]$IsDefault

   PrinterObject([string]$Name)
    {
        #Add-Type -AssemblyName System.Printing
        #Add-Type -AssemblyName ReachFramework
        $this.Server = New-Object System.Printing.PrintServer -ArgumentList [System.Printing.PrintSystemDesiredAccess]::AdministrateServer
        $this.Queue =  New-Object System.Printing.PrintQueue (($this.Server), ($this.Server.GetPrintQueues() | 
        Where-Object {$_.Name -match $Name} | Select-Object -ExpandProperty Name))

        $this.Ticket = $this.Queue.UserPrintTicket
        $this.Unit = Get-WmiObject -Query "SELECT * FROM Win32_Printer WHERE Name LIKE `"%$Name%`""
    }

    PrinterObject([string]$Name, [bool]$IsNetwork)
    {
        #Add-Type -AssemblyName System.Printing
        #Add-Type -AssemblyName ReachFramework
        if($IsNetwork -eq $true) {
        $this.Server = New-Object System.Printing.PrintServer ("\\Server")
        $this.Queue =  New-Object System.Printing.PrintQueue (($this.Server), ($this.Server.GetPrintQueues() | 
        Where-Object {$_.Name -match $Name} | Select-Object -ExpandProperty Name))

        $this.Ticket = $this.Queue.UserPrintTicket
        $this.Unit = Get-WmiObject -Query "SELECT * FROM Win32_Printer WHERE Name LIKE `"%$Name%`""
        }
        else {
        $This.Server = New-Object System.Printing.PrintServer -argumentList [System.Printing.PrintSystemDesiredAccess]::AdministrateServer
        $this.Queue =  New-Object System.Printing.PrintQueue (($this.Server), ($this.Server.GetPrintQueues() | 
        Where-Object {$_.Name -match $Name} | Select-Object -ExpandProperty Name))

        $this.Ticket = $this.Queue.UserPrintTicket
        $this.Unit = Get-WmiObject -Query "SELECT * FROM Win32_Printer WHERE Name LIKE `"%$Name%`"" }
    }
    [void]SetPrintTicket([int]$Copies, [string]$Collation, [string]$Duplex)
    {
        $this.Ticket.CopyCount = $Copies
        $this.Ticket.Collation = $Collation
        $this.Ticket.Duplexing = $Duplex
        $this.Queue.Commit()
    }

    [Object]GetJobs($Option)
    {
            if($Option -eq 1) { return $this.Queue.GetPrintJobInfoCollection() | Sort-Object -Property JobIdentifier | Select-Object -First 1}
            else { return $this.Queue.GetPrintJobInfoCollection() }
    }
    static [Object]ShowAllPrinters()
    {
        Return Get-WmiObject -Class Win32_Printer | Select-Object -Property Name, SystemName
    }

}
+6
source share
3 answers

Each PowerShell script is fully parsed before the first statement in the script is executed. An unsolvable type name token inside a class definition is considered a parsing error. To solve your problem, you need to load your types before the class definition is parsed, so the class definition must be in a separate file. For example:

Main.ps1:

Add-Type -AssemblyName System.Printing
Add-Type -AssemblyName ReachFramework

. $PSScriptRoot\Class.ps1

Class.ps1:

using namespace System.Management
using namespace System.Printing

Class PrinterObject
{
    [string]$Name
    [PrintServer]$Server
    [PrintQueue]$Queue
    [PrintTicket]$Ticket
    [ManagementObject]$Unit
    [bool]$IsDefault
}

- Class.ps1 Invoke-Expression . , .

Add-Type -AssemblyName System.Printing
Add-Type -AssemblyName ReachFramework

Invoke-Expression @‘
    using namespace System.Management
    using namespace System.Printing

    Class PrinterObject
    {
        [string]$Name
        [PrintServer]$Server
        [PrintQueue]$Queue
        [PrintTicket]$Ticket
        [ManagementObject]$Unit
        [bool]$IsDefault
    }
’@
+11

PetSerAl:

using assembly , Windows PowerShell v5.1/PowerShell Core v6.1, , , .

GitHub, .

0

( ) . , :

Add-Type -AssemblyName PresentationCore,PresentationFramework

class ExampleClass {
    $object

    ExampleClass ($anotherClass) {
        $this.object = $anotherClass
    }

    [void] Show () {
        $this.object::Show('Hello')
    }
}

$y = [ExampleClass]::new([System.Windows.MessageBox])
$y.Show()

, - , , Unable to find type [System.Windows.MessageBox].

Add-Type -AssemblyName PresentationCore,PresentationFramework

class ExampleClass2 {
    $object

    ExampleClass () {
        $this.object = [System.Windows.MessageBox]
    }

    [void] Show () {
        $this.object::Show('Hello')
    }
}
0

Source: https://habr.com/ru/post/1623019/


All Articles