NtDeviceFunctions.ps1
# Copyright 2021 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. <# .SYNOPSIS Open a filter communications port. .DESCRIPTION This cmdlet opens a filter communication port by name. .PARAMETER Path Specify the path to the filter communication port. .PARAMETER SyncHandle Specify to make the handle synchronous. .PARAMETER Context Specify optional context buffer. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Filter.FilterConnectionPort .EXAMPLE Get-FilterConnectionPort -Path "\FilterDriver" Open the filter communication port named \FilterDriver. #> function Get-FilterConnectionPort { [CmdletBinding()] Param( [parameter(Mandatory, Position = 0)] [string]$Path, [switch]$SyncHandle, [byte[]]$Context = $null ) [NtApiDotNet.Win32.Filter.FilterConnectionPort]::Open($Path, $SyncHandle, $Context) | Write-Output } <# .SYNOPSIS Sends a message to a filter connection port. .DESCRIPTION This cmdlet sends and receives a message on a filter connection port. .PARAMETER Port Specify the port to send on. .PARAMETER Input Optional input data. .PARAMETER MaximumOutput Specify maximum output data. .INPUTS None .OUTPUTS byte[] .EXAMPLE Send-FilterConnectionPort -Port $port -Input @(1, 2, 3, 4) -MaximumOutput 100 Send a 4 byte message and receive at most 100 bytes. #> function Send-FilterConnectionPort { [CmdletBinding()] Param( [parameter(Mandatory, Position = 0)] [NtApiDotNet.Win32.Filter.FilterConnectionPort]$Port, [byte[]]$Input = $null, [int]$MaximumOutput = 0 ) $Port.SendMessage($Input, $MaximumOutput) | Write-Output -NoEnumerate } <# .SYNOPSIS Get list of filter drivers loaded on the system. .DESCRIPTION This cmdlet enumerates the list of filter drivers loaded on the system. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Filter.FilterDriver[] .EXAMPLE Get-FilterDriver Get list of filter drivers. #> function Get-FilterDriver { [NtApiDotNet.Win32.Filter.FilterManagerUtils]::GetFilterDrivers() | Write-Output } <# .SYNOPSIS Get list of filter driver instances on the system. .DESCRIPTION This cmdlet enumerates the list of filter driver instances for a specified filter driver. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Filter.FilterInstance[] .EXAMPLE Get-FilterDriverInstance Get list of filter driver instances for all filter drivers. .EXAMPLE Get-FilterDriverInstance -FilterName "luafv" Get list of filter driver instances for the "luafv" driver. #> function Get-FilterDriverInstance { [CmdletBinding(DefaultParameterSetName = "All")] Param( [parameter(Mandatory, Position = 0, ParameterSetName = "FromName")] [string]$FilterName ) switch($PSCmdlet.ParameterSetName) { "All" { [NtApiDotNet.Win32.Filter.FilterManagerUtils]::GetFilterDriverInstances() | Write-Output } "FromName" { [NtApiDotNet.Win32.Filter.FilterManagerUtils]::GetFilterDriverInstances($FilterName) | Write-Output } } } <# .SYNOPSIS Get list of filter driver instances on the system. .DESCRIPTION This cmdlet enumerates the list of filter driver instances for a specified filter driver. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Filter.FilterVolume[] .EXAMPLE Get-FilterDriverVolume Get list of filter driver volumes. #> function Get-FilterDriverVolume { [NtApiDotNet.Win32.Filter.FilterManagerUtils]::GetFilterVolumes() | Write-Output } <# .SYNOPSIS Get list of filter driver volume instances on the system. .DESCRIPTION This cmdlet enumerates the list of filter driver volume instances for a specified filter driver. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Filter.FilterInstance[] .EXAMPLE Get-FilterDriverVolumeInstance Get list of filter driver instances for all filter driver volumes. .EXAMPLE Get-FilterDriverInstance -VolumeName "C:\" Get list of filter driver volume instances for the C: drive. #> function Get-FilterDriverVolumeInstance { [CmdletBinding(DefaultParameterSetName = "All")] Param( [parameter(Mandatory, Position = 0, ParameterSetName = "FromName")] [string]$VolumeName ) switch($PSCmdlet.ParameterSetName) { "All" { [NtApiDotNet.Win32.Filter.FilterManagerUtils]::GetFilterVolumeInstances() | Write-Output } "FromName" { [NtApiDotNet.Win32.Filter.FilterManagerUtils]::GetFilterVolumeInstances($VolumeName) | Write-Output } } } <# .SYNOPSIS Get the device setup classes. .DESCRIPTION This cmdlet gets device setup classes, either all installed or from a GUID/Name. .PARAMETER Name The name of the setup class. .PARAMETER Class The GUID of the setup class. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Device.DeviceSetupClass .EXAMPLE Get-NtDeviceSetupClass Get all device setup classes. .EXAMPLE Get-NtDeviceSetupClass -Class '6BDD1FC1-810F-11D0-BEC7-08002BE20920' Get the device setup class for the specified GUID. .EXAMPLE Get-NtDeviceSetupClass -Name 'USB' Get the device setup class for the USB class. #> function Get-NtDeviceSetupClass { [CmdletBinding(DefaultParameterSetName = "All")] Param( [parameter(Mandatory, Position = 0, ParameterSetName = "FromName")] [string]$Name, [parameter(Mandatory, ParameterSetName = "FromClass", ValueFromPipelineByPropertyName)] [guid]$Class ) PROCESS { switch($PSCmdlet.ParameterSetName) { "All" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceSetupClasses() | Write-Output } "FromName" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceSetupClasses() | Where-Object Name -eq $Name | Write-Output } "FromClass" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceSetupClass($Class) | Write-Output } } } } <# .SYNOPSIS Get the device interface classes. .DESCRIPTION This cmdlet gets device interface classes, either all installed or from a GUID. .PARAMETER Class The GUID of the interface class. .PARAMETER All Get all devices including ones not present. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Device.DeviceInterfaceClass .EXAMPLE Get-NtDeviceInterfaceClass Get all device interface classes. .EXAMPLE Get-NtDeviceInterfaceClass -Class '6BDD1FC1-810F-11D0-BEC7-08002BE20920' Get the device interface class for the specified GUID. #> function Get-NtDeviceInterfaceClass { [CmdletBinding(DefaultParameterSetName = "All")] Param( [parameter(Mandatory, Position = 0, ParameterSetName = "FromClass")] [guid]$Class, [switch]$All ) switch($PSCmdlet.ParameterSetName) { "All" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceInterfaceClasses($All) | Write-Output } "FromClass" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceInterfaceClass($Class, $All) | Write-Output } } } <# .SYNOPSIS Get the device node. .DESCRIPTION This cmdlet gets device nodes, either all present or from a GUID/Name. .PARAMETER Class The GUID of the setup class. .PARAMETER All Get all device instances. The default is to only get present instances. .PARAMETER Tree Get all device nodes as a tree. .PARAMETER InstanceId Get device from instance ID. .PARAMETER LinkName Specify a symbolic link name to resolve the device node. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Device.DeviceNode .EXAMPLE Get-NtDeviceNode Get all present device instances. .EXAMPLE Get-NtDeviceNode -All Get all device instances. .EXAMPLE Get-NtDeviceNode -Class '6BDD1FC1-810F-11D0-BEC7-08002BE20920' Get the device instances class for the specified setup class GUID. .EXAMPLE Get-NtDeviceNode -Tree Get all device instances in a tree structure. .EXAMPLE Get-NtDeviceNode -PDOName \Device\HarddiskVolume3 Get the device node with a specified PDO. .EXAMPLE Get-NtDeviceNode -LinkName \??\C: Get the device node with a specified symbolic link. #> function Get-NtDeviceNode { [CmdletBinding(DefaultParameterSetName = "All")] Param( [parameter(Mandatory, ParameterSetName = "FromClass", ValueFromPipelineByPropertyName)] [guid]$Class, [parameter(ParameterSetName = "FromClass")] [parameter(ParameterSetName = "All")] [switch]$All, [parameter(Mandatory, ParameterSetName = "FromTree")] [switch]$Tree, [parameter(Mandatory, ParameterSetName = "FromInstanceId")] [string]$InstanceId, [parameter(Mandatory, ParameterSetName = "FromPDOName")] [string]$PDOName, [parameter(ParameterSetName = "FromLinkName")] [string]$LinkName ) PROCESS { switch($PSCmdlet.ParameterSetName) { "All" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceNodeList($All) | Write-Output } "FromClass" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceNodeList($Class, $All) | Write-Output } "FromTree" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceNodeTree() | Write-Output } "FromInstanceId" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceNode($InstanceId) | Write-Output } "FromPDOName" { Get-NtDeviceNode | Where-Object PDOName -eq $PDOName } "FromLinkName" { try { $PDOName = Get-NtSymbolicLinkTarget -Path $LinkName -Resolve Get-NtDeviceNode | Where-Object PDOName -eq $PDOName } catch { Write-Error $_ } } } } } <# .SYNOPSIS Get device properties. .DESCRIPTION This cmdlet gets device properties. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Device.DeviceProperty[] .EXAMPLE Get-NtDeviceProperty -Device $dev Get all properties for a device. #> function Get-NtDeviceProperty { [CmdletBinding(DefaultParameterSetName = "FromDevice")] Param( [parameter(Mandatory, ParameterSetName = "FromDevice", ValueFromPipeline)] [NtApiDotNet.Win32.Device.IDevicePropertyProvider]$Device ) PROCESS { switch($PSCmdlet.ParameterSetName) { "FromDevice" { $Device.GetProperties() | Write-Output } } } } <# .SYNOPSIS Get device node children. .DESCRIPTION This cmdlet gets device node children. .PARAMETER Node The device node to query the children for. .PARAMETER Recurse Recursively get child nodes. .PARAMETER Depth Specify the maximum depth for the recursion. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Device.DeviceTreeNode[] .EXAMPLE Get-NtDeviceNodeChild -Node $dev Get all children for a device node .EXAMPLE Get-NtDeviceNodeChild -Node $dev -Recurse Get all children for a device node recursively. .EXAMPLE Get-NtDeviceNodeChild -Node $dev -Recurse -Depth 2 Get all children for a device node recursively with max depth of 2. #> function Get-NtDeviceNodeChild { [CmdletBinding(DefaultParameterSetName = "All")] Param( [parameter(Mandatory, ParameterSetName = "FromNode", Position = 0)] [NtApiDotNet.Win32.Device.DeviceNode]$Node, [switch]$Recurse, [int]$Depth = [int]::MaxValue ) if ($Recurse -and $Depth -lt 1) { return } try { if ($Node -isNot [NtApiDotNet.Win32.Device.DeviceTreeNode]) { $Node = [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceNodeTree($Node.InstanceId) } switch($PSCmdlet.ParameterSetName) { "FromNode" { if ($Recurse) { $recdepth = $Depth - 1 $Device.Children | ForEach-Object { Get-NtDeviceNodeChild -Node $_ -Recurse -Depth $recdepth } } $Node.Children | Write-Output } } } catch { Write-Error $_ } } <# .SYNOPSIS Get device instance parent. .DESCRIPTION This cmdlet gets device node parent. .PARAMETER Node The device node to query the parent for. .PARAMETER Recurse Get all parents recursively. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Device.DeviceNode[] .EXAMPLE Get-NtDeviceNodeParent -Node $dev Get parent for device node. .EXAMPLE Get-NtDeviceNodeParent -Node $dev -Recurse Get all parents for device node. #> function Get-NtDeviceNodeParent { [CmdletBinding(DefaultParameterSetName = "All")] Param( [parameter(Mandatory, ParameterSetName = "FromNode", Position = 0)] [NtApiDotNet.Win32.Device.DeviceNode]$Node, [switch]$Recurse ) switch($PSCmdlet.ParameterSetName) { "FromNode" { if ($Recurse) { $Node.GetParentNodes() | Write-Output } else { $Node.Parent | Write-Output } } } } <# .SYNOPSIS Get device stack for a node. .DESCRIPTION This cmdlet gets device node's device stack. .PARAMETER Node The device node to query device stack for. .PARAMETER Summary Summarize the device stack as a single line. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Device.DeviceStackEntry[] .EXAMPLE Get-NtDeviceNodeStack -Node $dev Get device stack for device node. #> function Get-NtDeviceNodeStack { [CmdletBinding(DefaultParameterSetName = "FromNode")] Param( [parameter(Mandatory, ParameterSetName = "FromNode", Position = 0, ValueFromPipeline)] [NtApiDotNet.Win32.Device.DeviceNode]$Node, [switch]$Summary ) PROCESS { switch($PSCmdlet.ParameterSetName) { "FromNode" { if ($Summary) { [string]::Join(", ", $Node.DeviceStack) | Write-Output } else { $Node.DeviceStack | Write-Output } } } } } <# .SYNOPSIS Get the device interface instances. .DESCRIPTION This cmdlet gets device interface instances either all present, from a GUID or instance name. .PARAMETER Class The GUID of the interface class. .PARAMETER Instance The path the instance symbolic link. .INPUTS None .OUTPUTS NtApiDotNet.Win32.Device.DeviceInterfaceInstance[] .EXAMPLE Get-NtDeviceInterfaceInstance Get all device interface instances. .EXAMPLE Get-NtDeviceInterfaceInstance -Class '6BDD1FC1-810F-11D0-BEC7-08002BE20920' Get the device interface instances for the specified GUID. .EXAMPLE Get-NtDeviceInterfaceInstance -Instance '\\?\HSIDS&1234' Get the device interface instances for the instance symbolic link path. #> function Get-NtDeviceInterfaceInstance { [CmdletBinding(DefaultParameterSetName = "All")] Param( [parameter(Mandatory, Position = 0, ParameterSetName = "FromClass")] [guid]$Class, [parameter(Mandatory, Position = 0, ParameterSetName = "FromInstance")] [string]$Instance ) switch($PSCmdlet.ParameterSetName) { "All" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceInterfaceInstances() | Write-Output } "FromClass" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceInterfaceInstances($Class) | Write-Output } "FromInstance" { [NtApiDotNet.Win32.Device.DeviceUtils]::GetDeviceInterfaceInstance($Instance) | Write-Output } } } |