Enums 在powershell中使用intPtr和使用add-type封送处理
我正在尝试在Powershell中添加类型。我正在使用netapi32.dll使用NetSessionEnum函数。 这几乎有效,但并不完全有效。当使用零级查询时,我可以得到一个结果。当使用任何其他选项进行查询时,IDE或powershell会话在尝试安装PtrToStructure时会崩溃。我完全卡住了 我认为这与结构尺寸有关,但不是很确定。 如果有人能给我指出正确的方向或提供一些建议,那将是非常棒的Enums 在powershell中使用intPtr和使用add-type封送处理,enums,struct,powershell-2.0,add-type,Enums,Struct,Powershell 2.0,Add Type,我正在尝试在Powershell中添加类型。我正在使用netapi32.dll使用NetSessionEnum函数。 这几乎有效,但并不完全有效。当使用零级查询时,我可以得到一个结果。当使用任何其他选项进行查询时,IDE或powershell会话在尝试安装PtrToStructure时会崩溃。我完全卡住了 我认为这与结构尺寸有关,但不是很确定。 如果有人能给我指出正确的方向或提供一些建议,那将是非常棒的 函数获取网络会话{ param( [字符串]$ComputerName=“”, [字符串]
函数获取网络会话{
param(
[字符串]$ComputerName=“”,
[字符串]$ComputerSession=“”,
[字符串]$UserName=“”,
[int]$QueryLevel
)
$DebugPreference='continue'
$signature=@'
[DllImport(“netapi32.dll”,SetLastError=true)]
公共静态外部int NetSessionEnum(
[In,marshallas(UnmanagedType.LPWStr)]字符串ServerName,
[In,marshallas(UnmanagedType.LPWStr)]字符串UncClientName,
[In,marshallas(UnmanagedType.LPWStr)]字符串用户名,
Int32级,
输出IntPtr bufptr,
int prefmaxlen,
参考Int32 entriesread,
参考Int32 totalentries,
参考Int32恢复(U手柄);
'@
$SessionInfo结构=@'
名称空间pinvoke{
使用制度;
使用System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
公共结构会话\u信息\u 0
{
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi0_cname;
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
公共结构会话\u信息\u 1
{
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi1_cname;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi1_用户名;
公开单元sesi1\u num\u打开;
公众参与时间;
公共用户空闲时间;
公共uint sesi1_用户_标志;
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
公共结构会话信息2
{
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi2_cname;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi2_用户名;
公开单元sesi2_num_打开;
公众参与时间;
公共用户空闲时间;
公共uint sesi2_用户_标志;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi2\u cltype\u name;
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
公共结构会话\u信息\u 10
{
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi10_cname;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi10_用户名;
公众参与时间;
公共用户空闲时间;
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
公共结构会话\u信息\u 502
{
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi502_cname;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi502_用户名;
打开公共uint sesi502_num_;
公共uint sesi502_时间;
公共uint sesi502\u空闲时间;
公共uint sesi502_用户_标志;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi502\u cltype\u名称;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串sesi502_传输;
}
公共枚举NERR
{
///
///手术很成功。
///
NERR_Success=0,
///
///更多可读取的数据。数据错误获取所有数据。
///
错误\u更多\u数据=234,
///
///网络浏览器不可用。
///
错误\u NO\u BROWSER\u SERVERS\u FOUND=6118,
///
///指定的级别对此调用无效。
///
错误\u无效\u级别=124,
///
///安全上下文没有进行此调用的权限。
///
错误访问被拒绝=5,
///
///参数不正确。
///
错误\u无效\u参数=87,
///
///内存不足。
///
错误\u内存不足\u=8,
///
///无法联系资源。连接超时。
///
错误\网络\忙=54,
///
///找不到网络路径。
///
错误\坏\网络路径=53,
///
///没有可用的网络连接来拨打电话。
///
错误号网络=1222,
///
///指针无效。
///
错误\u无效\u句柄\u状态=1609,
///
///扩展错误。
///
错误扩展错误=1208,
///
///基地。
///
NERR_基准=2100,
///
///未知目录。
///
NERR_UnknownDevDir=(NERR_基数+16),
///
///服务器上已存在重复共享。
///
净收益率=净收益率基数+18,
///
///内存分配太小。
///
内尔库布夫托斯莫尔=(内尔库基+23)
}
公共枚举会话\u级别
{
///
///零
///
级别0=0,
///
///一个
///
第1级=1,
///
///两个
///
第2级=2级,
///
///十
///
10级=10级,
///
///五百零二
///
等级502=502
}
}
'@
#添加自定义结构和枚举
添加类型$SessionInfo结构
#添加函数定义
添加类型-MemberDefinition$signature-Name Win32Util-Namespace Pinvoke-Using Pinvoke
if([Pinvoke.SESSION\u LEVEL]::LEVEL\u 0-eq$QueryLevel){$x=新对象Pinvoke.SESSION\u INFO\u 0}
if([Pinvoke.SESSION\u LEVEL]::LEVEL\u 1-eq$QueryLevel){$x=新对象Pinvoke.SESSION\u INFO\u 1}
if([Pinvoke.SESSION\u LEVEL]::LEVEL\u 2-eq$QueryLevel){$x=新对象Pinvoke.SESSION\u INFO\u 2}
if([Pinvoke.SESSION\u LEVEL]::LEVEL\u 10-eq$QueryLevel){$x=新对象Pinvoke.SESSION\u INFO\u 10}
if([Pinvoke.SESSION\u LEVEL]::LEVEL\u 502-eq$QueryLevel){$x=新对象Pinvoke.SESSION\u INFO\u 502}
#声明引用变量
$type=$x.gettype()
写入调试“$type.tostring()”
$ptrInfo=0
$EntriesRed=0
$TotalRead=0
$ResumeHandle=0
#调用函数
$Result=[pinvoke.Win32Util]::NetSessionEnum($ComputerName,$ComputerSession,$UserName,0,[ref]$ptrInfo,-1,[ref]$EntriesRed,[ref]$TotalRead,[ref]$Resu
function Get-NetSessions {
param(
[string]$ComputerName = "",
[string]$ComputerSession = "",
[string]$UserName = "",
[int]$QueryLevel
)
$DebugPreference = 'continue'
$signature = @'
[DllImport("netapi32.dll", SetLastError=true)]
public static extern int NetSessionEnum(
[In,MarshalAs(UnmanagedType.LPWStr)] string ServerName,
[In,MarshalAs(UnmanagedType.LPWStr)] string UncClientName,
[In,MarshalAs(UnmanagedType.LPWStr)] string UserName,
Int32 Level,
out IntPtr bufptr,
int prefmaxlen,
ref Int32 entriesread,
ref Int32 totalentries,
ref Int32 resume_handle);
'@
$SessionInfoStructures = @'
namespace pinvoke {
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SESSION_INFO_0
{
[MarshalAs(UnmanagedType.LPWStr)]
public String sesi0_cname;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SESSION_INFO_1
{
[MarshalAs(UnmanagedType.LPWStr)]
public string sesi1_cname;
[MarshalAs(UnmanagedType.LPWStr)]
public string sesi1_username;
public uint sesi1_num_opens;
public uint sesi1_time;
public uint sesi1_idle_time;
public uint sesi1_user_flag;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SESSION_INFO_2
{
[MarshalAs(UnmanagedType.LPWStr)]
public string sesi2_cname;
[MarshalAs(UnmanagedType.LPWStr)]
public string sesi2_username;
public uint sesi2_num_opens;
public uint sesi2_time;
public uint sesi2_idle_time;
public uint sesi2_user_flags;
[MarshalAs(UnmanagedType.LPWStr)]
public string sesi2_cltype_name;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SESSION_INFO_10
{
[MarshalAs(UnmanagedType.LPWStr)]
public string sesi10_cname;
[MarshalAs(UnmanagedType.LPWStr)]
public string sesi10_username;
public uint sesi10_time;
public uint sesi10_idle_time;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct SESSION_INFO_502
{
[MarshalAs(UnmanagedType.LPWStr)]
public string sesi502_cname;
[MarshalAs(UnmanagedType.LPWStr)]
public string sesi502_username;
public uint sesi502_num_opens;
public uint sesi502_time;
public uint sesi502_idle_time;
public uint sesi502_user_flags;
[MarshalAs(UnmanagedType.LPWStr)]
public string sesi502_cltype_name;
[MarshalAs(UnmanagedType.LPWStr)]
public string sesi502_transport;
}
public enum NERR
{
/// <summary>
/// Operation was a success.
/// </summary>
NERR_Success = 0,
/// <summary>
/// More data available to read. dderror getting all data.
/// </summary>
ERROR_MORE_DATA = 234,
/// <summary>
/// Network browsers not available.
/// </summary>
ERROR_NO_BROWSER_SERVERS_FOUND = 6118,
/// <summary>
/// LEVEL specified is not valid for this call.
/// </summary>
ERROR_INVALID_LEVEL = 124,
/// <summary>
/// Security context does not have permission to make this call.
/// </summary>
ERROR_ACCESS_DENIED = 5,
/// <summary>
/// Parameter was incorrect.
/// </summary>
ERROR_INVALID_PARAMETER = 87,
/// <summary>
/// Out of memory.
/// </summary>
ERROR_NOT_ENOUGH_MEMORY = 8,
/// <summary>
/// Unable to contact resource. Connection timed out.
/// </summary>
ERROR_NETWORK_BUSY = 54,
/// <summary>
/// Network Path not found.
/// </summary>
ERROR_BAD_NETPATH = 53,
/// <summary>
/// No available network connection to make call.
/// </summary>
ERROR_NO_NETWORK = 1222,
/// <summary>
/// Pointer is not valid.
/// </summary>
ERROR_INVALID_HANDLE_STATE = 1609,
/// <summary>
/// Extended Error.
/// </summary>
ERROR_EXTENDED_ERROR= 1208,
/// <summary>
/// Base.
/// </summary>
NERR_BASE = 2100,
/// <summary>
/// Unknown Directory.
/// </summary>
NERR_UnknownDevDir = (NERR_BASE + 16),
/// <summary>
/// Duplicate Share already exists on server.
/// </summary>
NERR_DuplicateShare = (NERR_BASE + 18),
/// <summary>
/// Memory allocation was to small.
/// </summary>
NERR_BufTooSmall = (NERR_BASE + 23)
}
public enum SESSION_LEVEL
{
/// <summary>
/// ZERO
/// </summary>
LEVEL_0 = 0,
/// <summary>
/// ONE
/// </summary>
LEVEL_1 = 1,
/// <summary>
/// TWO
/// </summary>
LEVEL_2 = 2,
/// <summary>
/// TEN
/// </summary>
LEVEL_10 = 10,
/// <summary>
/// FIVE HUNDRED AND TWO
/// </summary>
LEVEL_502 = 502
}
}
'@
# Add the custom structures and enums
Add-Type $SessionInfoStructures
# Add the function definition
Add-Type -MemberDefinition $signature -Name Win32Util -Namespace Pinvoke -Using Pinvoke
if ([Pinvoke.SESSION_LEVEL]::LEVEL_0 -eq $QueryLevel) {$x = New-Object pinvoke.SESSION_INFO_0}
if ([Pinvoke.SESSION_LEVEL]::LEVEL_1 -eq $QueryLevel) {$x = New-Object pinvoke.SESSION_INFO_1}
if ([Pinvoke.SESSION_LEVEL]::LEVEL_2 -eq $QueryLevel) {$x = New-Object pinvoke.SESSION_INFO_2}
if ([Pinvoke.SESSION_LEVEL]::LEVEL_10 -eq $QueryLevel) {$x = New-Object pinvoke.SESSION_INFO_10}
if ([Pinvoke.SESSION_LEVEL]::LEVEL_502 -eq $QueryLevel) {$x = New-Object pinvoke.SESSION_INFO_502}
# Declare the reference variables
$type = $x.gettype()
Write-Debug "$type.tostring()"
$ptrInfo = 0
$EntriesRed = 0
$TotalRead = 0
$ResumeHandle = 0
# Call the function
$Result = [pinvoke.Win32Util]::NetSessionEnum($ComputerName,$ComputerSession,$UserName,0,[ref]$ptrInfo,-1,[ref]$EntriesRed,[ref]$TotalRead,[ref]$ResumeHandle)
$Result
if ($Result -eq ([pinvoke.NERR]::NERR_Success)){
Write-Debug 'Result is success'
Write-Debug "IntPtr $ptrInfo"
Write-Debug "Entries read $EntriesRed"
Write-Debug "Total Read $TotalRead"
# Locate the offset of the initial intPtr
$offset = $ptrInfo.ToInt64()
Write-Debug "Starting Offset $offset"
# Work out how mutch to increment the pointer by finding out the size of the structure
$Increment = [System.Runtime.Interopservices.Marshal]::SizeOf($x)
Write-Debug "Increment $Increment"
for ($i = 0; ($i -lt $EntriesRed); $i++){
$newintptr = New-Object system.Intptr -ArgumentList $offset
Write-Debug "Newintptr `[$i`] $newintptr"
$Info = [system.runtime.interopservices.marshal]::PtrToStructure($newintptr,$type)
$Info | Select-Object *
$offset = $newintptr.ToInt64()
$offset += $increment
}
}
else
{
# switch ($Result)
# {
# ([Pinvoke.NERR]::ERROR_ACCESS_DENIED) {Write-Host "The user does not have access to the requested information."}
# ([Pinvoke.NERR]::ERROR_INVALID_LEVEL) {Write-Host "The value specified for the level parameter is not valid."}
# ([Pinvoke.NERR]::ERROR_INVALID_PARAMETER) {Write-Host 'The specified parameter is not valid.'}
# ([Pinvoke.NERR]::ERROR_MORE_DATA) {Write-Host 'More entries are available. Specify a large enough buffer to receive all entries.'}
# ([Pinvoke.NERR]::ERROR_NOT_ENOUGH_MEMORY) {Write-Host 'Insufficient memory is available.'}
# ([Pinvoke.NERR]::NERR_ClientNameNotFound) {Write-Host 'A session does not exist with the computer name.'}
# ([Pinvoke.NERR]::NERR_InvalidComputer) {Write-Host 'The computer name is not valid.'}
# ([Pinvoke.NERR]::NERR_ClientNameNotFound) {Write-Host 'The user name could not be found.'}
# }
}
}
Get-NetSessions -QueryLevel 0
$Info = [system.runtime.interopservices.marshal]::PtrToStructure($newintptr,$type)
$Info = [system.runtime.interopservices.marshal]::PtrToStructure($newintptr,[System.Type]$type)