I downloaded the Get-NetSession.ps1 script from the TechNet Script Center Gallery, (Browse code samples | Microsoft Docs) but I needed the number of open files, so I substituted SESSION_INFO_10 for SESSION_INFO_1 and defined the two extra fields. It runs and returns the open files, but it crashes ISE right after that.
I added code to get the user DisplayName, Telephone and Extension. Also added code to format the SessionTime and IdleTime. Still need to add code to display the OpenFiles correctly.
Does anyone have any ideas why its crashing ISE?
Running on a Windows 10 Enterprise Edition workstation.
Thanks.
Function Get-NetSession { <# .SYNOPSIS Queries the remote system for all net sessions .DESCRIPTION Queries the remote system for all net sessions .PARAMETER Computername Computer to query for net sessions .PARAMETER Username Specifies a user to look for in the net sessions .PARAMETER IncludeSelf Includes the current user session used to run this command .NOTES Name: Get-NetSession Author: Boe Prox Version History: 1.1 //Boe Prox - 1 August 2016 - Added IncludeSelf parameter to include displaying the session created from command otherwise this data is not presented - Bug fixes 1.0 //Boe Prox - 28 July 2016 - Initial build .EXAMPLE Get-NetSession -Computername Server1 Computername : Server1 SourceComputer : Workstation1 SourceIPAddress : 192.168.2.56 Username : bobsmith SessionTime : 0 IdleTime : 0 Computername : Server1 SourceComputer : Workstation2 SourceIPAddress : 192.168.2.110 Username : joeuser SessionTime : 348607 IdleTime : 345850 Description ----------- Returns all net sessions on Server1 #> [cmdletbinding()] Param ( [parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)] [string[]]$Computername, [parameter()] [string]$Username = '', [parameter()] [switch]$IncludeSelf ) Begin { If ($PSBoundParameters.ContainsKey('Debug')) { $DebugPreference = 'Continue' } If (-NOT $PSBoundParameters.ContainsKey('IncludeSelf')) { $Hostname = "$($env:COMPUTERNAME).$($env:USERDNSDOMAIN)" Write-Verbose "Excluding $Hostname and $($env:USERNAME)" } #region Reflection Try { [void][Net.Session] } Catch { Write-Verbose "Building pinvoke via reflection" #region Module Builder $Domain = [AppDomain]::CurrentDomain $DynAssembly = New-Object System.Reflection.AssemblyName('NetSession') $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, [System.Reflection.Emit.AssemblyBuilderAccess]::Run) # Only run in memory $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('NetSessionModule', $False) #endregion Module Builder #region Custom Attribute Builder $ctor = [System.Runtime.InteropServices.MarshalAsAttribute].GetConstructor(@([System.Runtime.InteropServices.UnmanagedType])) $CustomAttribute = [System.Runtime.InteropServices.UnmanagedType]::LPWStr $CustomAttributeBuilder = New-Object System.Reflection.Emit.CustomAttributeBuilder -ArgumentList $ctor, $CustomAttribute #endregion Custom Attribute Builder #region Struct #region SESSION_INFO_1 $Attributes = 'AutoLayout, AnsiClass, Class, Public, SequentialLayout, Sealed, BeforeFieldInit' $STRUCT_TypeBuilder = $ModuleBuilder.DefineType('SESSION_INFO_1', $Attributes, [System.ValueType], 8, 0x0) $Field = $STRUCT_TypeBuilder.DefineField('OriginatingHost', [string], 'Public') $Field.SetCustomAttribute($CustomAttributeBuilder) $Field = $STRUCT_TypeBuilder.DefineField('DomainUser', [string], 'Public') $Field.SetCustomAttribute($CustomAttributeBuilder) [void]$STRUCT_TypeBuilder.DefineField('OpenFiles', [uint32], 'Public') [void]$STRUCT_TypeBuilder.DefineField('SessionTime', [uint32], 'Public') [void]$STRUCT_TypeBuilder.DefineField('IdleTime', [uint32], 'Public') [void]$STRUCT_TypeBuilder.DefineField('UserFlags', [uint32], 'Public') [void]$STRUCT_TypeBuilder.CreateType() #endregion SESSION_INFO_1 #endregion Struct $TypeBuilder = $ModuleBuilder.DefineType('Net.Session', 'Public, Class') #region Methods #region NetSessionEnum Method $PInvokeMethod = $TypeBuilder.DefineMethod( 'NetSessionEnum', #Method Name [Reflection.MethodAttributes] 'PrivateScope, Public, Static, HideBySig, PinvokeImpl', #Method Attributes [int32], #Method Return Type [Type[]] @( [string], [string], [string], [int32], [intptr].MakeByRefType(), [int], [int32].MakeByRefType(), [int32].MakeByRefType(), [int32].MakeByRefType() ) #Method Parameters ) #Define first three parameters with custom attributes 1..3 | ForEach { $Parameter = $PInvokeMethod.DefineParameter( $_, [System.Reflection.ParameterAttributes]::In, $Null ) $Parameter.SetCustomAttribute( $CustomAttributeBuilder ) } $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String])) $FieldArray = [Reflection.FieldInfo[]] @( [Runtime.InteropServices.DllImportAttribute].GetField('EntryPoint'), [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError') [Runtime.InteropServices.DllImportAttribute].GetField('ExactSpelling') [Runtime.InteropServices.DllImportAttribute].GetField('PreserveSig') ) $FieldValueArray = [Object[]] @( 'NetSessionEnum', #CASE SENSITIVE!! $True, $True, $True ) $CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder( $DllImportConstructor, @('Netapi32.dll'), $FieldArray, $FieldValueArray ) $PInvokeMethod.SetCustomAttribute($CustomAttribute) #endregion NetSessionEnum Method #region NetApiBufferFree Method $PInvokeMethod = $TypeBuilder.DefineMethod( 'NetApiBufferFree', #Method Name [Reflection.MethodAttributes] 'PrivateScope, Public, Static, HideBySig, PinvokeImpl', #Method Attributes [int], #Method Return Type [Type[]] @( [intptr] ) #Method Parameters ) $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String])) $FieldArray = [Reflection.FieldInfo[]] @( [Runtime.InteropServices.DllImportAttribute].GetField('EntryPoint'), [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError') [Runtime.InteropServices.DllImportAttribute].GetField('ExactSpelling') [Runtime.InteropServices.DllImportAttribute].GetField('PreserveSig') ) $FieldValueArray = [Object[]] @( 'NetApiBufferFree', #CASE SENSITIVE!! $True, $True, $True ) $CustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder( $DllImportConstructor, @('Netapi32.dll'), $FieldArray, $FieldValueArray ) $PInvokeMethod.SetCustomAttribute($CustomAttribute) #endregion NetApiBufferFree Method #endregion Methods [void]$TypeBuilder.CreateType() } #endregion Reflection } Process { ForEach ($Computer in $Computername) { Write-Verbose "Scanning $Computer" $SessionInfo1 = New-Object -TypeName SESSION_INFO_1 $SessionInfo1Size = [System.Runtime.InteropServices.Marshal]::SizeOf($SessionInfo1) $Buffer = [IntPtr]::Zero [int32]$EntriesRead = 0 [int32]$TotalEntries = 0 [int32]$ResumeHandle = 0 $Return = [Net.Session]::NetSessionEnum( $Computer, "", $Username, 10, [ref]$Buffer, -1, [ref]$EntriesRead, [ref]$TotalEntries, [ref]$ResumeHandle ) $LastError = [ComponentModel.Win32Exception][Runtime.InteropServices.Marshal]::GetLastWin32Error() If ([System.IntPtr]::Size -eq 4) { $BufferOffset = $Buffer.ToInt32() } Else { $BufferOffset = $Buffer.ToInt64() } For ($Count = 0; ($Count -lt $EntriesRead); $Count++){ $NewBuffer = New-Object System.Intptr -ArgumentList $BufferOffset $Info = [System.Runtime.Interopservices.Marshal]::PtrToStructure($NewBuffer,[type]$SessionInfo1.GetType()) $Info | ForEach { $IP = $_.OriginatingHost.Trim('\\') Try { $ResolvedName = [Net.DNS]::GetHostByAddress($IP).HostName } Catch { $ResolvedName = 'N/A' } $Object = [pscustomobject]@{ Computername = $Computer SourceComputer = $ResolvedName SourceIPAddress = $IP Username = $_.DomainUser DisplayName = (Get-ADUser -Identity $_.DomainUser -Properties displayname).displayname Telephone = (Get-ADUser -Identity $_.DomainUser -Properties telephoneNumber).telephoneNumber Extension = (Get-ADUser -Identity $_.DomainUser -Properties extensionAttribute3).extensionAttribute3 OpenFiles = "$($_.OpenFiles)" ## Added to script ## SessionTime = [TimeSpan]::FromSeconds($_.SessionTime).ToString('hh\:mm\:ss') IdleTime = [TimeSpan]::FromSeconds($_.IdleTime).ToString('hh\:mm\:ss') } $Object.pstypenames.insert(0,'Net.SessionInformation') If (($PSBoundParameters.ContainsKey('IncludeSelf'))) { $Object } ElseIf (-NOT ((($ResolvedName -eq $Hostname) -OR ($IP -eq $env:COMPUTERNAME)) -AND ($_.DomainUser -eq $env:USERNAME))) { $Object } } $BufferOffset = $BufferOffset + $SessionInfo1Size } [void][Net.Session]::NetApiBufferFree($Buffer) } } End {} }