" When the value of the variable is an array, the += operator appends theIn the second part of the script below, I pump the results of a foreach loop into an explicitly typed compound assignment variable ("$RecurseList"):
values on the right side of the operator to the array. Unless the array is
explicitly typed by casting, you can append any type of value to the array..."
Historic Blog. No longer active. A script repository that stopped at Powershell 4.0 is at www.rmfdevelopment.com/PowerShell_Scripts . My historic blog (no longer active) on Network Security ( http://thinking-about-network-security.blogspot.com ) is also Powershell heavy. AS of 2/27/2014 all Scripts are PS 4.0.
Saturday, September 3, 2011
Compound variable assignment as [array[]] based storage
Below is a function I have written to demonstrate a function which recursively checks ownership and access for files modified within a given time span. What I call to your attention is the ability to use the assignment operator ('+=') to store data recursively as highlighted in salmon. This is mentioned in 'about_assignment_operators' in the help for Powershell V2:
Labels:
Compound Assignment;
Wednesday, August 24, 2011
Storing 'Get-counter' data
You can do this:
((get-counter -counter '\\rmfvpc\TCPv4\Connections Established').countersamples) | % {$_.CookedValue}
and this:
(get-counter -counter '\\rmfvpc\TCPv4\Connections Established').Readings | findstr ^[0-9]
and this:
(get-counter -counter '\\rmfvpc\TCPv4\Connections Established' -continuous -sampleinterval 2)
but you can't do this:
((get-counter -counter '\\rmfvpc\TCPv4\Connections Established').countersamples) | % {$_.CookedValue}
and this:
(get-counter -counter '\\rmfvpc\TCPv4\Connections Established').Readings | findstr ^[0-9]
and this:
(get-counter -counter '\\rmfvpc\TCPv4\Connections Established' -continuous -sampleinterval 2)
but you can't do this:
Labels:
isolating 'get-counter' data
Monday, August 22, 2011
Some addendum on modules
If you add modules like PSUserTools from Microsoft you receive some enhanced functionality. You also receive some well conceived script. After you have imported your modules ('import-module'), you can use a function like that below to list all the exported commands:
function Global:get-module_exports {
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true)]
$ModName
)
$commands=(get-module $ModName).ExportedCommands
[Array[]]$list=(($commands).Values) | %{$_.Name} | Sort
$list
}
Labels:
Modules,
PSUserTools
Friday, May 6, 2011
$$ Recursion?
After reading Lee Holmes $$ blog post, I realized the $$ command has some recursive properties.
You can assign a function to the $$ variable and then init that function as follows:
You can assign a function to the $$ variable and then init that function as follows:
Function Repeat-History { $$='function gh {get-history}' Invoke-History $$ gh }
Labels:
$$ functional programming
Wednesday, February 9, 2011
Displaying IP addresses with Windows Powershell
How many IP Addresses on a Windows 7 system?
Here are two different Powershell commands that produce a list of IPv4 and IPv6 addresses on the same Windows 7 workstation. One parses 'ipconfig' and validates five addresses through '[System.Net.IPaddress]'. The other uses 'gwmi' and the format of the addresses it produces will not similarly validate. Aside from the formatting of the object produced, I cannot understand why they will not validate. It appears here I am extracting IPv6 anycast and broadcast addresses with 'ipconfig' that 'gwmi' is not giving me.
$IPAddress_ipconfig=(ipconfig | Select-string Address) -split ": " | Select-string -notmatch ". ."
foreach ($IP in $IPAddress_ipconfig) {([System.Net.IPaddress]::Parse("$IP")).IPAddressToString}
fe80::6172:6ecf:2d05:b0ae%12
192.168.0.11
fe80::cddc:ceef:b717:a5ac%11
2001:0:4137:9e76:30c3:129:3f57:fff4
fe80::30c3:129:3f57:fff4%17
(Get-WmiObject Win32_NetworkAdapterConfiguration | ? {$_.IPAddress} | Select IPaddress | fc -expand CoreOnly | findstr [0-9])
fe80::cddc:ceef:b717:a5ac
192.168.0.11
fe80::6172:6ecf:2d05:b0ae
Here are two different Powershell commands that produce a list of IPv4 and IPv6 addresses on the same Windows 7 workstation. One parses 'ipconfig' and validates five addresses through '[System.Net.IPaddress]'. The other uses 'gwmi' and the format of the addresses it produces will not similarly validate. Aside from the formatting of the object produced, I cannot understand why they will not validate. It appears here I am extracting IPv6 anycast and broadcast addresses with 'ipconfig' that 'gwmi' is not giving me.
$IPAddress_ipconfig=(ipconfig | Select-string Address) -split ": " | Select-string -notmatch ". ."
foreach ($IP in $IPAddress_ipconfig) {([System.Net.IPaddress]::Parse("$IP")).IPAddressToString}
fe80::6172:6ecf:2d05:b0ae%12
192.168.0.11
fe80::cddc:ceef:b717:a5ac%11
2001:0:4137:9e76:30c3:129:3f57:fff4
fe80::30c3:129:3f57:fff4%17
(Get-WmiObject Win32_NetworkAdapterConfiguration | ? {$_.IPAddress} | Select IPaddress | fc -expand CoreOnly | findstr [0-9])
fe80::cddc:ceef:b717:a5ac
192.168.0.11
fe80::6172:6ecf:2d05:b0ae
Labels:
Displaying IP Addresses
Saturday, January 8, 2011
ping multiple subnets
# 'ping-multiple_subnets.ps1' # All Rights Reserved Ryan M. Ferris r.10:34 PM 1/7/2011
# Powershell V2 functions to ping multiple-subnets
# Consists of three functions: (ping-subnet, ping-ip , ping-multi)
# ping-subnet : .NET $ping.send - a single (simple) eight byte ICMP packet
# ping-ip : WMI 'test-connection' - a single (wmi info) eight byte ICMP packet
# ping-multi : wrapper function
# first create multiple Class C ranges: e.g.: # $IPRange = 0..5 | %{"192.168.$_"}
# use 'ping-multi' to discover them: e.g.: # $IPRange | % {ping-multi $_}
# The .NET $ping.send is much faster than WMI although 'test-connection' returns more# information and can be configured to do authentication and impersonation
# Essentially, 'ping-subnet' does discovery that it pumps to 'ping-ip' which # creates csv files named per subnet per pass.
function global:Ping-Subnet
{
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string]$Network,
[array] $subnet=@(0..254),
[int32] $buffersize=8,
[Int32] $timeout=10,
[Int32] $TTL=128,
[bool] $fragment=$false,
[string]$ErrorActionPreference="silentlycontinue"
)
$ping = new-object System.Net.NetworkInformation.Ping
$pingoptions = new-object System.Net.NetworkInformation.PingOptions
$pingoptions.ttl=$TTL
$pingoptions.dontfragment=$fragment
$Global:SNIPs=( $subnet | % -process {$Ping.Send("$Network.$_", $timeout, $buffersize, $PingOptions)} |
where {$_.Status -eq "Success"})
$Global:IPs= $SNIPs | % {$_.Address.IPAddressToString}
}
function global:Ping-ip
{
[CmdletBinding()]
Param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string]$computername,
[int32] $buffersize=8,
[int32] $count=1,
[Int32] $TimeToLive=128,
[Int32] $Delay=1,
[string] $ErrorActionPreference="silentlycontinue"
)
$global:result= Test-connection -computername $computername `
-buffersize $buffersize `
-count $count `
-TimeToLive $TimeToLive `
-Delay $Delay
$global:icmp_out = New-Object PSObject -Property @{
IPv4 = $result.IPv4Address.IPAddressToString
IPv6 = $result.IPv6Address.IPAddressToString
BytesSent = $result.BufferSize
BytesReturned = $result.ReplySize
ResponseTime = $result.ResponseTime
ReplyInc = $result.ReplyInconsistency
} | Select-Object IPv4,IPv6,BytesSent,BytesReturned,Responsetime,ReplyInc
if ($icmp_out -ne $null)
{$ICMP_out | ConvertTo-Csv -NoTypeInformation | out-file -width 120 -append -NoClobber (write "$3OCT.csv")}
}
function ping-multi
{
Param(
[Parameter(Mandatory=$true,ValueFromPipeline=$true)]
[string] $Global:3OCT
)
$3OCT | % {ping-subnet $_}
$IPs | % {ping-ip $_}
}
Labels:
ping multiple subnets
Tuesday, January 4, 2011
Using Test-Connection
'Test-Connection' is Powershell V2's GWMI-based icmp test cmdlet that returns considerable amounts of information in object format. 'Test-Connection' also has the ability to authenticate (at various levels) to the computer whose ICMP responses it is testing, but I do not discuss that in this post. 'Test-Connection' can return a number of errors, which I found difficult to trap, throw, or try-catch-finally. So, like some others (1,2), I punted on error-trapping with:
[string] $ErrorActionPreference="silentlycontinue" (Yea, I know...what a wimp...)
Although, 'Test-Connection' is slower than System.Net.NetworkInformation.Ping will probably ever be, it does return considerable amounts of useful information. Below is the function 'Ping-IP' with the returned object and some statistical results from 'measure-object'. I've created a hash table and renamed six of the properties. Notice how I can use 'Test-Connection' to check for IPv4 and IPv6 connections simultaneously (if you have an existing IPv6 interface).
Tuesday, December 21, 2010
Powershell log time-stamping
The function 'logtime' below will work as a logging function in scripts
$FileTime=[DateTime]::Now.ToFileTime()
function logtime{
$date = [DateTime]::Now.Day
$hour = [DateTime]::Now.TimeOfDay.Hours
$minutes = [DateTime]::Now.TimeOfDay.Minutes
$seconds = [DateTime]::Now.TimeOfDay.Seconds
$ms = [DateTime]::Now.TimeOfDay.Milliseconds
[object]$logtime = New-Object PSObject -Property @{
date=$date
hour=$hour
minutes=$minutes
seconds=$seconds
ms=$ms
}
write $logtime | ft -HideTableHeaders -AutoSize -Property date,hour,minutes,seconds,ms | out-file -append -noclobber $PWD\$FileTime
}
[output]
PS C:\Users\rferrisx\Documents> gc 129374235* | more
21 8 45 43 821
21 8 51 12 604
21 8 51 12 616
21 8 51 12 656
21 8 51 12 662
$FileTime=[DateTime]::Now.ToFileTime()
function logtime{
$date = [DateTime]::Now.Day
$hour = [DateTime]::Now.TimeOfDay.Hours
$minutes = [DateTime]::Now.TimeOfDay.Minutes
$seconds = [DateTime]::Now.TimeOfDay.Seconds
$ms = [DateTime]::Now.TimeOfDay.Milliseconds
[object]$logtime = New-Object PSObject -Property @{
date=$date
hour=$hour
minutes=$minutes
seconds=$seconds
ms=$ms
}
write $logtime | ft -HideTableHeaders -AutoSize -Property date,hour,minutes,seconds,ms | out-file -append -noclobber $PWD\$FileTime
}
[output]
PS C:\Users\rferrisx\Documents> gc 129374235* | more
21 8 45 43 821
21 8 51 12 604
21 8 51 12 616
21 8 51 12 656
21 8 51 12 662
Labels:
Powershell time-stamping logging
Wednesday, December 8, 2010
System.Net.NetworkInformation.Ping
Here are some Powershell ping notes from System.Net.NetworkInformation.Ping. Powershell v 2.0 provides for the gwmi based Win32_PingStatus in the 'Test-Connection' cmdlet . 'Test-connection' provides a wealth of information. However this post simply examines how to use:
#Set up the ping options
$ping = new-object System.Net.NetworkInformation.Ping
$pingoptions = new-object System.Net.NetworkInformation.PingOptions
$pingoptions.ttl=255
$pingoptions.dontfragment=$false
# Here is the overload
# From $ping.send.overloaddefinitions use: System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions options)
#now ping a subnet with one line of code
(1..254 | % -process {$Ping.Send("192.168.0.$_", 10, 64, $PingOptions)})
# or (stop output) or redirect to a variable:
$a=(1..254 | % -process {$Ping.Send("192.168.0.$_", 10, 64, $PingOptions)})
This gives us something interesting like this:
PS C:\ps1> $a | where {$_.Status -eq "Success"} | ft * -auto
Status Address RoundtripTime Options Buffer
------ ------- ------------- ------- ------
Success 192.168.0.1 2 System.Net.NetworkInformation.PingOptions {64}
Success 192.168.0.6 1 System.Net.NetworkInformation.PingOptions {64}
Success 192.168.0.11 0 System.Net.NetworkInformation.PingOptions {64}
Success 192.168.0.13 0 System.Net.NetworkInformation.PingOptions {64}
#ping a multiple names
$DNS_array="google.com", "googel.com", "googley.com"
($DNS_array | % -process {$Ping.Send("$_", 10, 64, $PingOptions)})
Status : Success
Address : 72.14.213.99
RoundtripTime : 29
Options : System.Net.NetworkInformation.PingOptions
Buffer : {64, 0, 0, 0...}
Status : Success
Address : 74.125.224.17
RoundtripTime : 38
Options : System.Net.NetworkInformation.PingOptions
Buffer : {64}
Status : Success
Address : 74.117.221.11
RoundtripTime : 96
Options : System.Net.NetworkInformation.PingOptions
Buffer : {64}
($DNS_array | % -process {$Ping.Send("$_", 10, 64, $PingOptions)}) |
% {$_.Address.IPAddressToString +","+ $_.Status +","+ $_.RoundTripTime}
72.14.213.99,Success,25
74.125.224.17,Success,38
74.117.221.11,Success,98
Something more clever to ping multiple subnets is needed. The code below isn't very fast. The use of a filter might speed it up. However, you can make it faster by specifying exactly the hosts you want in $Host_array.
#ping multiple subnets
[array]$Host_array=1..20
$Subnet_array="192.168.0","192.168.1","192.168.2"
$count=$Subnet_array.count
$i=0
do
{
$global:out = $host_array | % -process {$Ping.Send($Subnet_array[$i]+"."+$_ , 1, 64, $PingOptions)}
$out | % {if ($_.Address) {$_.Address.IPAddressToString +","+ $_.Status +","+ $_.RoundTripTime}}
$i=$i+1
}
while ($i -lt $count)
- System.Net.NetworkInformation.Ping
- System.Net.NetworkInformation.PingOptions
#Set up the ping options
$ping = new-object System.Net.NetworkInformation.Ping
$pingoptions = new-object System.Net.NetworkInformation.PingOptions
$pingoptions.ttl=255
$pingoptions.dontfragment=$false
# Here is the overload
# From $ping.send.overloaddefinitions use: System.Net.NetworkInformation.PingReply Send(string hostNameOrAddress, int timeout, byte[] buffer, System.Net.NetworkInformation.PingOptions options)
#now ping a subnet with one line of code
(1..254 | % -process {$Ping.Send("192.168.0.$_", 10, 64, $PingOptions)})
# or (stop output) or redirect to a variable:
$a=(1..254 | % -process {$Ping.Send("192.168.0.$_", 10, 64, $PingOptions)})
This gives us something interesting like this:
PS C:\ps1> $a | where {$_.Status -eq "Success"} | ft * -auto
Status Address RoundtripTime Options Buffer
------ ------- ------------- ------- ------
Success 192.168.0.1 2 System.Net.NetworkInformation.PingOptions {64}
Success 192.168.0.6 1 System.Net.NetworkInformation.PingOptions {64}
Success 192.168.0.11 0 System.Net.NetworkInformation.PingOptions {64}
Success 192.168.0.13 0 System.Net.NetworkInformation.PingOptions {64}
If you functionalize/filterize the output :
function pingsn {1..254 | % -process {$Ping.Send("192.168.0.$_", 10, 64, $PingOptions)}}
filter success {if ($_.status -eq "Success") {($_.Address.IPAddressToString)+" "+($_.roundtriptime)}}
you get a similar output:
pingsn | success
192.168.0.1 1
192.168.0.6 1
192.168.0.9 0
192.168.0.11 1
We can also ping and array of names (as below) and retrieve similar information if we pipe the output to a variable. Or we can do something more CSV like:function pingsn {1..254 | % -process {$Ping.Send("192.168.0.$_", 10, 64, $PingOptions)}}
filter success {if ($_.status -eq "Success") {($_.Address.IPAddressToString)+" "+($_.roundtriptime)}}
you get a similar output:
pingsn | success
192.168.0.1 1
192.168.0.6 1
192.168.0.9 0
192.168.0.11 1
#ping a multiple names
$DNS_array="google.com", "googel.com", "googley.com"
($DNS_array | % -process {$Ping.Send("$_", 10, 64, $PingOptions)})
Status : Success
Address : 72.14.213.99
RoundtripTime : 29
Options : System.Net.NetworkInformation.PingOptions
Buffer : {64, 0, 0, 0...}
Status : Success
Address : 74.125.224.17
RoundtripTime : 38
Options : System.Net.NetworkInformation.PingOptions
Buffer : {64}
Status : Success
Address : 74.117.221.11
RoundtripTime : 96
Options : System.Net.NetworkInformation.PingOptions
Buffer : {64}
($DNS_array | % -process {$Ping.Send("$_", 10, 64, $PingOptions)}) |
% {$_.Address.IPAddressToString +","+ $_.Status +","+ $_.RoundTripTime}
72.14.213.99,Success,25
74.125.224.17,Success,38
74.117.221.11,Success,98
Something more clever to ping multiple subnets is needed. The code below isn't very fast. The use of a filter might speed it up. However, you can make it faster by specifying exactly the hosts you want in $Host_array.
#ping multiple subnets
[array]$Host_array=1..20
$Subnet_array="192.168.0","192.168.1","192.168.2"
$count=$Subnet_array.count
$i=0
do
{
$global:out = $host_array | % -process {$Ping.Send($Subnet_array[$i]+"."+$_ , 1, 64, $PingOptions)}
$out | % {if ($_.Address) {$_.Address.IPAddressToString +","+ $_.Status +","+ $_.RoundTripTime}}
$i=$i+1
}
while ($i -lt $count)
Labels:
Powershell: Ping IP Ranges
Saturday, July 31, 2010
Looking at Process, Threads, Modules with Powershell 2.0
I have published "Looking at Processes, Modules, and Threads with Powershell 2.0 Part I". The paper concerns itself with comparing Processes, Modules, and Threads and offers some discussion for comparing their changes over time. See also:
http://www.rmfdevelopment.com/PowerShell_Scripts/diff_PMT.ps1
http://rmfdevelopment.com/PowerShell_Scripts/diff_PMT_adv.ps1
http://www.rmfdevelopment.com/PowerShell_Scripts/diff_PMT.ps1
http://rmfdevelopment.com/PowerShell_Scripts/diff_PMT_adv.ps1
Wednesday, May 5, 2010
Which processes are communicating on Vista? Part II
This is a faster method of telling which processes are communicating. It feeds netstat output to tasklist:
@for /f "tokens=1-5" %a in ('@netstat -nto ^| findstr /V Active ^| findstr /V Proto') do @tasklist /FO CSV /V /FI "PID eq %e" /NH
If put in a batch file that is properly escaped:
@for /f "tokens=1-5" %%a in ('@netstat -nto ^| findstr /V Active ^| findstr /V Proto') do @tasklist /FO CSV /V /FI "PID eq %%e" /NH
and then run as below, it gives you process information on Established TCP connections. Tested on Vista. :
@ntob_ts.cmd | sort /+2
"chrome.exe","3192","Console","1","77,012 K","Running","RMFVista\Admin","0:02:54","Daily Alerts - Google Analytics - Google Chrome"
"chrome.exe","3192","Console","1","77,012 K","Running","RMFVista\Admin","0:02:54","Daily Alerts - Google Analytics - Google Chrome"
"opera.exe","4092","Console","1","346,284 K","Running","RMFVista\Admin","0:09:03","http://sn114w.snt114.mail.live.com/default.aspx?wa=wsignin1.0 - Opera"
"opera.exe","4092","Console","1","346,328 K","Running","RMFVista\Admin","0:09:03","http://sn114w.snt114.mail.live.com/default.aspx?wa=wsignin1.0 - Opera"
This batch file below includes netstat endpoints but seems to randomly attach an IP address to the System Idle process ("0"):
@echo off
for /f "tokens=1-5" %%a in ('@netstat -nto ^| findstr /V Active ^| findstr /V Proto') do set EP=%%c& set PID=%%e& call :loop
goto EOF
:loop
@echo "%EP%", | findstr /V "ECHO"
@tasklist /FO CSV /V /FI "PID eq %PID%" /NH
@echo " " >NUL
:EOF
[output]
"74.125.19.17:443",
"chrome.exe","3192","Console","1","89,400 K","Running","RMFVista\Admin","0:03:34","Blogger: Horizontal Logic - Edit Post "Which Processes are communicating on Vista? Part I...
" - Google Chrome"
"74.125.19.19:443",
"chrome.exe","3192","Console","1","89,400 K","Running","RMFVista\Admin","0:03:34","Blogger: Horizontal Logic - Edit Post "Which Processes are communicating on Vista? Part I...
" - Google Chrome"
"74.125.19.19:443",
"opera.exe","4092","Console","1","346,312 K","Running","RMFVista\Admin","0:09:40","http://sn114w.snt114.mail.live.com/default.aspx?wa=wsignin1.0 - Opera"
"74.125.19.19:443",
"opera.exe","4092","Console","1","346,324 K","Running","RMFVista\Admin","0:09:40","http://sn114w.snt114.mail.live.com/default.aspx?wa=wsignin1.0 - Opera"
"74.125.19.101:80",
"chrome.exe","3192","Console","1","89,400 K","Running","RMFVista\Admin","0:03:34","Blogger: Horizontal Logic - Edit Post "Which Processes are communicating on Vista? Part I...
" - Google Chrome"
"74.125.10.23:80",
"chrome.exe","3192","Console","1","89,400 K","Running","RMFVista\Admin","0:03:34","Blogger: Horizontal Logic - Edit Post "Which Processes are communicating on Vista? Part I...
" - Google Chrome"
"76.96.30.119:110",
"System Idle Process","0","Services","0","24 K","Unknown","NT AUTHORITY\SYSTEM","24:51:17","N/A"
"85.13.200.108:110",
"WinMail.exe","4456","Console","1","179,712 K","Running","RMFVista\Admin","0:34:00","Google Alert - TCP/IP"
@for /f "tokens=1-5" %a in ('@netstat -nto ^| findstr /V Active ^| findstr /V Proto') do @tasklist /FO CSV /V /FI "PID eq %e" /NH
If put in a batch file that is properly escaped:
@for /f "tokens=1-5" %%a in ('@netstat -nto ^| findstr /V Active ^| findstr /V Proto') do @tasklist /FO CSV /V /FI "PID eq %%e" /NH
and then run as below, it gives you process information on Established TCP connections. Tested on Vista. :
@ntob_ts.cmd | sort /+2
"chrome.exe","3192","Console","1","77,012 K","Running","RMFVista\Admin","0:02:54","Daily Alerts - Google Analytics - Google Chrome"
"chrome.exe","3192","Console","1","77,012 K","Running","RMFVista\Admin","0:02:54","Daily Alerts - Google Analytics - Google Chrome"
"opera.exe","4092","Console","1","346,284 K","Running","RMFVista\Admin","0:09:03","http://sn114w.snt114.mail.live.com/default.aspx?wa=wsignin1.0 - Opera"
"opera.exe","4092","Console","1","346,328 K","Running","RMFVista\Admin","0:09:03","http://sn114w.snt114.mail.live.com/default.aspx?wa=wsignin1.0 - Opera"
This batch file below includes netstat endpoints but seems to randomly attach an IP address to the System Idle process ("0"):
@echo off
for /f "tokens=1-5" %%a in ('@netstat -nto ^| findstr /V Active ^| findstr /V Proto') do set EP=%%c& set PID=%%e& call :loop
goto EOF
:loop
@echo "%EP%", | findstr /V "ECHO"
@tasklist /FO CSV /V /FI "PID eq %PID%" /NH
@echo " " >NUL
:EOF
[output]
"74.125.19.17:443",
"chrome.exe","3192","Console","1","89,400 K","Running","RMFVista\Admin","0:03:34","Blogger: Horizontal Logic - Edit Post "Which Processes are communicating on Vista? Part I...
" - Google Chrome"
"74.125.19.19:443",
"chrome.exe","3192","Console","1","89,400 K","Running","RMFVista\Admin","0:03:34","Blogger: Horizontal Logic - Edit Post "Which Processes are communicating on Vista? Part I...
" - Google Chrome"
"74.125.19.19:443",
"opera.exe","4092","Console","1","346,312 K","Running","RMFVista\Admin","0:09:40","http://sn114w.snt114.mail.live.com/default.aspx?wa=wsignin1.0 - Opera"
"74.125.19.19:443",
"opera.exe","4092","Console","1","346,324 K","Running","RMFVista\Admin","0:09:40","http://sn114w.snt114.mail.live.com/default.aspx?wa=wsignin1.0 - Opera"
"74.125.19.101:80",
"chrome.exe","3192","Console","1","89,400 K","Running","RMFVista\Admin","0:03:34","Blogger: Horizontal Logic - Edit Post "Which Processes are communicating on Vista? Part I...
" - Google Chrome"
"74.125.10.23:80",
"chrome.exe","3192","Console","1","89,400 K","Running","RMFVista\Admin","0:03:34","Blogger: Horizontal Logic - Edit Post "Which Processes are communicating on Vista? Part I...
" - Google Chrome"
"76.96.30.119:110",
"System Idle Process","0","Services","0","24 K","Unknown","NT AUTHORITY\SYSTEM","24:51:17","N/A"
"85.13.200.108:110",
"WinMail.exe","4456","Console","1","179,712 K","Running","RMFVista\Admin","0:34:00","Google Alert - TCP/IP"
Labels:
netstat tasklist Windows Vista
Monday, March 8, 2010
Which services are communicating on Vista?
What I want to know is which services are engaging in network communication. How they are changing over time. Network Monitor 3.3 tracks data packets back to executables but has an "unknown" category that carries a lot of data. TCPView gives a dynamic list of Process, Protocol, Address and Port in real-time. In the batch files below I pipe uniq tcpvcon output of process IDs to tasklist /SVC and have FC detect what has changes. Tasklist /SVC is slow however.
@echo off
@for /f %%i in ('tcpvcon -a -c ^| gawk -F"," '{print $3}' ^| sort ^| uniq') do @(tasklist /NH /FO CSV /SVC /FI "PID eq %%i") >&1>> temp1
@for /f %%i in ('tcpvcon -a -c ^| gawk -F"," '{print $3}' ^| sort ^| uniq') do @(tasklist /NH /FO CSV /SVC /FI "PID eq %%i") >&1>> temp2
fc temp1 temp2 > &1>> diff
@echo off
:top
del temp1
del temp2
@for /f %%i in ('tcpvcon -a -c ^| gawk -F"," '{print $3}' ^| sort ^| uniq') do @(tasklist /NH /FO CSV /SVC /FI "PID eq %%i") >&1>> temp1
@for /f %%i in ('tcpvcon -a -c ^| gawk -F"," '{print $3}' ^| sort ^| uniq') do @(tasklist /NH /FO CSV /SVC /FI "PID eq %%i") >&1>> temp2
fc temp1 temp2
goto top
Some relatively simple Powershell also helps detect which services are communicating:
@echo off
@for /f %%i in ('tcpvcon -a -c ^| gawk -F"," '{print $3}' ^| sort ^| uniq') do @(tasklist /NH /FO CSV /SVC /FI "PID eq %%i") >&1>> temp1
@for /f %%i in ('tcpvcon -a -c ^| gawk -F"," '{print $3}' ^| sort ^| uniq') do @(tasklist /NH /FO CSV /SVC /FI "PID eq %%i") >&1>> temp2
fc temp1 temp2 > &1>> diff
@echo off
:top
del temp1
del temp2
@for /f %%i in ('tcpvcon -a -c ^| gawk -F"," '{print $3}' ^| sort ^| uniq') do @(tasklist /NH /FO CSV /SVC /FI "PID eq %%i") >&1>> temp1
@for /f %%i in ('tcpvcon -a -c ^| gawk -F"," '{print $3}' ^| sort ^| uniq') do @(tasklist /NH /FO CSV /SVC /FI "PID eq %%i") >&1>> temp2
fc temp1 temp2
goto top
Some relatively simple Powershell also helps detect which services are communicating:
$global:svchost = get-wmiObject win32_process -filter "name='svchost.exe'"
$global:win32_handle = $svchost | foreach { gwmi -query "Select * from win32_service where processID = $($_.handle)" }
$global:Sort_handle = $win32_handle | sort processID, Name
$global:Sort_svchost = $svchost | sort processID
$Sort_handle | format-table processID,name,state, startmode,Started,AcceptStop,Description -AutoSize
$Sort_svchost | format-table ProcessID,ThreadCount,HandleCount,WS,VM,KernelModeTime,ReadOperationCount,ReadTransferCount,OtherTransferCount -Autosize
Labels:
tcpvcon;tasklist;
Sunday, June 14, 2009
Enumerating running modules
Some code worth publishing (from some work I am doing over at RMF Network Security on Conficker, worm detection, etc: ):
$Global:ps = ps
$ps_count = $ps.count
write "Process Count = $ps_count"
$Global:all_modules = 0..$ps_count |%{$ps[$_].Modules} | Select Size,ModuleName,FileName,FileVersion
$allmod_count = $all_modules.count
write "All instances of loaded modules = $allmod_count"
$Global:unique_all_modules = $all_modules | Select -property ModuleName | Sort -Unique -property ModuleName
$uniqmod_count = $unique_all_modules.count
write "All uniq module names = $uniqmod_count"
$Global:all_modules_memory = $all_modules | Select -property ModuleName,Size | Sort -property Size
$Global:MO_all_mod_mem = $all_modules_memory | measure-object -property Size -sum
$Global:CountModMem = $MO_all_mod_mem.count
$Global:SumModMem = $MO_all_mod_mem.sum
$SumModMemMB = ( ( $SumModMem * 1000)/ 1GB)
write "Sum of $CountModMem modules memory size = $SumModMemMB GB"
Labels:
PS;modules;memory
Tuesday, April 14, 2009
Wednesday, April 8, 2009
Gathering Network Statistics
# In PS CTP2v3, .NET access to IP statistics is non-existent. There are no static members
# for the interface statistics yet, although there are non static members:
[System.Net.NetworkInformation.IcmpV4Statistics].getmembers() | %{$_.name}
[System.Net.NetworkInformation.IPGlobalStatistics].getmembers() | %{$_.name}
Wednesday, April 1, 2009
Working with netmon caps in Powershell
An update to this post 8:32 PM 8/7/2009:
I have no path to loading nmcap files into powershell now that logparser does not work with Netmon 3.3 file format. I added my comment to this feature request:
https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=265564&SiteID=216
"The jump between 3.2 and 3.3 file formats/APIs broke logparser2.2 interface to netmon files which was extraordinarily useful since logparser would convert file formats, sql-lize queries, create charts and datagrids, etc. Examples are below. Granted this is probably a logparser (e.g. unsupported ware) defect, however...The real defect is here is that there is no path to convert Netmon 3.3 captures files to CSV.C:\Program Files (x86)\Log Parser 2.2>logparser -headers OFF -stats NO -i:NETMON -o:CSV "SELECT DateTime,SrcMAC,SrcPort,DstMAC,DstPort,WindowSize FROM32.cap"2009-01-13 11:37:53,00095B00F3DA,80,0013021A607B,2004,328902009-01-13 11:37:53,0013021A607B,2006,00095B00F3DA,80,163842009-01-13 11:37:54,00095B00F3DA,80,0013021A607B,2006,58402009-01-13 11:37:54,0013021A607B,2006,00095B00F3DA,80,175202009-01-13 11:37:54,0013021A607B,2006,00095B00F3DA,80,17520.....C:\Program Files (x86)\Log Parser 2.2>logparser -headers OFF -i:NETMON -o:CSV "SELECT DateTime,SrcMAC,SrcPort,DstMAC,DstPort,WindowSize FROM 33.cap"Statistics:-----------Elements processed: 0Elements output: 0Execution time: 0.01 seconds"
7:10 AM 4/2/2009: An update to this post
Once you have a capture in the form of an object, you can do interesting work with it in powershell:
$DstSrcPort_8NET = $capture where-object {($_.SrcIP -match "^8\." ) -or ($_.DstIP -match "^8\.")}
$DstSrcPort_8NET Sort DateTime -unique ft more
$DstSrcPort_8NET group-object DstPort Sort -descending Count
$DstSrcPort_8NET measure-object -average -minimum -maximum -property WindowSize
$a = $DstSrcPort_8NET Sort SrcIP -unique
$a %{[System.Net.DNS]::Resolve($_.SrcIP)}
In progress...concating collections of nmcap files and searching them for specific SrcIP and DstIp with Powershell and LogParser. This code is working now, but still "to be continued"...
I have no path to loading nmcap files into powershell now that logparser does not work with Netmon 3.3 file format. I added my comment to this feature request:
https://connect.microsoft.com/feedback/ViewFeedback.aspx?FeedbackID=265564&SiteID=216
"The jump between 3.2 and 3.3 file formats/APIs broke logparser2.2 interface to netmon files which was extraordinarily useful since logparser would convert file formats, sql-lize queries, create charts and datagrids, etc. Examples are below. Granted this is probably a logparser (e.g. unsupported ware) defect, however...The real defect is here is that there is no path to convert Netmon 3.3 captures files to CSV.C:\Program Files (x86)\Log Parser 2.2>logparser -headers OFF -stats NO -i:NETMON -o:CSV "SELECT DateTime,SrcMAC,SrcPort,DstMAC,DstPort,WindowSize FROM32.cap"2009-01-13 11:37:53,00095B00F3DA,80,0013021A607B,2004,328902009-01-13 11:37:53,0013021A607B,2006,00095B00F3DA,80,163842009-01-13 11:37:54,00095B00F3DA,80,0013021A607B,2006,58402009-01-13 11:37:54,0013021A607B,2006,00095B00F3DA,80,175202009-01-13 11:37:54,0013021A607B,2006,00095B00F3DA,80,17520.....C:\Program Files (x86)\Log Parser 2.2>logparser -headers OFF -i:NETMON -o:CSV "SELECT DateTime,SrcMAC,SrcPort,DstMAC,DstPort,WindowSize FROM 33.cap"Statistics:-----------Elements processed: 0Elements output: 0Execution time: 0.01 seconds"
7:10 AM 4/2/2009: An update to this post
Once you have a capture in the form of an object, you can do interesting work with it in powershell:
$DstSrcPort_8NET = $capture where-object {($_.SrcIP -match "^8\." ) -or ($_.DstIP -match "^8\.")}
$DstSrcPort_8NET Sort DateTime -unique ft more
$DstSrcPort_8NET group-object DstPort Sort -descending Count
$DstSrcPort_8NET measure-object -average -minimum -maximum -property WindowSize
$a = $DstSrcPort_8NET Sort SrcIP -unique
$a %{[System.Net.DNS]::Resolve($_.SrcIP)}
In progress...concating collections of nmcap files and searching them for specific SrcIP and DstIp with Powershell and LogParser. This code is working now, but still "to be continued"...
function Search-IP($IP_String)
{ #start function
(ls -name *.cap)
foreach-object -begin {$file =[DateTime]::now.ToFileTime().ToString()} `
-process {
$filename = $_ ;
$temp = logparser -headers OFF -stats NO -i:NETMON -o:CSV "SELECT DateTime,SrcIP,SrcPort,DstIP,DstPort,WindowSize FROM $filename" ;
out-file -inputobject $temp -append -noclobber -filepath $file} `
-end {
$header = "DateTime","SrcIP","SrcPort","DstIP","DstPort","WindowSize" ;
$Global:capture = Import-csv $file -header $header ;
$Global:MatchIPObject = $capture where-object {$_ -match $IP_String} ;
$Global:MatchIPString = Select-String $IP_String $file -AllMatches}
} #end function
:$MatchIPObject[0..10] ft
DateTime SrcIP SrcPort DstIP DstPort WindowSize
-------- ----- ------- ----- ------- ----------
2007-07-16 13:59:52 68.26.116.175 1169 66.133.124.56 443 16384
2007-07-16 13:59:52 66.133.124.56 443 68.26.116.175 1169 4140
2007-07-16 13:59:52 68.26.116.175 1169 66.133.124.56 443 16560
2007-07-16 13:59:52 68.26.116.175 1169 66.133.124.56 443 16560
2007-07-16 13:59:52 66.133.124.56 443 68.26.116.175 1169 4140
2007-07-16 13:59:52 68.26.116.175 1169 66.133.124.56 443 15753
2007-07-16 13:59:52 68.26.116.175 1169 66.133.124.56 443 15753
2007-07-16 13:59:52 68.26.116.175 1170 66.133.124.56 443 16384
2007-07-16 13:59:52 66.133.124.56 443 68.26.116.175 1169 4229
2007-07-16 13:59:52 66.133.124.56 443 68.26.116.175 1169 4229
2007-07-16 13:59:52 68.26.116.175 1169 66.133.124.56 443 15753
:$MatchIPString[0..10]
128830930248593750:7:2007-07-16 13:59:52,68.26.116.175,1169,66.133.124.56,443,16384
128830930248593750:9:2007-07-16 13:59:52,66.133.124.56,443,68.26.116.175,1169,4140
128830930248593750:10:2007-07-16 13:59:52,68.26.116.175,1169,66.133.124.56,443,16560
128830930248593750:11:2007-07-16 13:59:52,68.26.116.175,1169,66.133.124.56,443,16560
128830930248593750:12:2007-07-16 13:59:52,66.133.124.56,443,68.26.116.175,1169,4140
128830930248593750:13:2007-07-16 13:59:52,68.26.116.175,1169,66.133.124.56,443,15753
128830930248593750:14:2007-07-16 13:59:52,68.26.116.175,1169,66.133.124.56,443,15753
128830930248593750:15:2007-07-16 13:59:52,68.26.116.175,1170,66.133.124.56,443,16384
128830930248593750:16:2007-07-16 13:59:52,66.133.124.56,443,68.26.116.175,1169,4229
128830930248593750:17:2007-07-16 13:59:52,66.133.124.56,443,68.26.116.175,1169,4229
128830930248593750:18:2007-07-16 13:59:52,68.26.116.175,1169,66.133.124.56,443,15753
:$MatchIPObject[0..10] gm
TypeName: System.Management.Automation.PSCustomObject
Name MemberType Definition
---- ---------- ----------
Equals Method System.Boolean Equals(Object obj)
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
ToString Method System.String ToString()
DateTime NoteProperty System.String DateTime=2007-07-16 13:59:52
DstIP NoteProperty System.String DstIP=66.133.124.56
DstPort NoteProperty System.String DstPort=443
SrcIP NoteProperty System.String SrcIP=68.26.116.175
SrcPort NoteProperty System.String SrcPort=1169
WindowSize NoteProperty System.String WindowSize=16384
:$MatchIPString[0..10] gm
TypeName: Microsoft.PowerShell.Commands.MatchInfo
Name MemberType Definition
---- ---------- ----------
Equals Method System.Boolean Equals(Object obj)
GetHashCode Method System.Int32 GetHashCode()
GetType Method System.Type GetType()
ToString Method System.String ToString(), System.String ToString(String directory)
Context Property Microsoft.PowerShell.Commands.MatchInfoContext Context {get;set;}
Filename Property System.String Filename {get;}
IgnoreCase Property System.Boolean IgnoreCase {get;set;}
Line Property System.String Line {get;set;}
LineNumber Property System.Int32 LineNumber {get;set;}
Matches Property System.Text.RegularExpressions.Match[] Matches {get;set;}
Path Property System.String Path {get;set;}
Pattern Property System.String Pattern {get;set;}
Monday, March 30, 2009
I experimented with a powershell script in the start folder. I had some issues. I am still not sure how to get consecuitive commands that share the same environment running. So I simply appended my function name after defining it in my script. I did not use the "-file" option but invoked the script like a command from a cmd.exe file. This cmd.exe file still requires me to type an Administrative password after startup. Not quite sure how to get around that...
:: Powershell startup to pump established connections to the Event Log
echo Powershell -windowStyle hidden -noexit -noprofile "& D:\PS1\netstat_Established_log_startup.ps1" >TCPListen.cmd
runas /profile /env /user:Administrator TCPListen.cmd
Tuesday, March 24, 2009
Metadata
Jason Shirk's excellent post on meta-programming inspired this function and alias I have added to my profile to help me get a handle on the use and format of paramaters in CTP2 v3 scripts.
function Create-Metadata($args0) {
$args0 = new-object System.Management.Automation.CommandMetadata (get-command $args0)
[System.Management.Automation.ProxyCommand]::Create($args0) | out-file ProxyCommand.txt
more ProxyCommand.txt
}
Set-Alias cm Create-Metadata
Run as below:
CM("trace-command")
[CmdletBinding(DefaultParameterSetName='expressionSet')]
param(
[Parameter(ValueFromPipeline=$true)]
[System.Management.Automation.PSObject]
${InputObject},
[Parameter(Mandatory=$true, Position=0)]
[System.String[]]
${Name},
[Parameter(Position=2)]
[System.Management.Automation.PSTraceSourceOptions]
${Option},
[Parameter(ParameterSetName='expressionSet', Mandatory=$true, Position=1)]
[System.Management.Automation.ScriptBlock]
${Expression},
[Parameter(ParameterSetName='commandSet', Mandatory=$true, Position=1)]
[System.String]
${Command},
[Parameter(ParameterSetName='commandSet', ValueFromRemainingArguments=$true)]
[Alias('Args')]
[System.Object[]]
${ArgumentList},
[System.Diagnostics.TraceOptions]
${ListenerOption},
[Alias('PSPath')]
[System.String]
${FilePath},
.....
Some notes on FileVersionInfo, finding Modules, loaded dlls:
(get-process -id $pid).modules | %{$_} | fl * | more
Size : 152
Company : Microsoft Corporation
FileVersion : 6.1.6949.0 (fbl_srv_powershell_ctp(srvbld).081105-1651)
ProductVersion : 6.1.6949.0
Description : Windows PowerShell
Product : Microsoft? Windows? Operating System
ModuleName : PowerShell.exe
FileName : C:\WINDOWS\system32\WindowsPowerShell\v1.0\PowerShell.exe
BaseAddress : 579928064
ModuleMemorySize : 155648
EntryPointAddress : 579954429
FileVersionInfo : File: C:\WINDOWS\system32\WindowsPowerShell\v1.0\PowerShell.exe
InternalName: POWERSHELL
OriginalFilename: PowerShell.EXE
FileVersion: 6.1.6949.0 (fbl_srv_powershell_ctp(srvbld).081105-1651)
FileDescription: Windows PowerShell
Product: Microsoft? Windows? Operating System
ProductVersion: 6.1.6949.0
Debug: False
Patched: False
PreRelease: False
PrivateBuild: True
SpecialBuild: False
Language: English (United States)
....
A workable tlist substitute:
$a =foreach ($id in (get-process)) {write $id.Name,$id.Size,$id.modules}
$a | more
alg
Size(K) ModuleName FileName
------- ---------- --------
52 alg.exe C:\WINDOWS\System32\alg.exe
700 ntdll.dll C:\WINDOWS\system32\ntdll.dll
984 kernel32.dll C:\WINDOWS\system32\kernel32.dll
352 msvcrt.dll C:\WINDOWS\system32\msvcrt.dll
68 ATL.DLL C:\WINDOWS\System32\ATL.DLL
580 USER32.dll C:\WINDOWS\system32\USER32.dll
292 GDI32.dll C:\WINDOWS\system32\GDI32.dll
620 ADVAPI32.dll C:\WINDOWS\system32\ADVAPI32.dll
584 RPCRT4.dll C:\WINDOWS\system32\RPCRT4.dll
68 Secur32.dll C:\WINDOWS\system32\Secur32.dll
1268 ole32.dll C:\WINDOWS\system32\ole32.dll
556 OLEAUT32.dll C:\WINDOWS\system32\OLEAUT32.dll
36 WSOCK32.dll C:\WINDOWS\System32\WSOCK32.dll
.....
Monday, March 16, 2009
This will be worth some more investigation. I can send a Powershell array of cmd.exe strings to the cmd.exe interpreter and pass cmd.exe a Powershell "here string" that will passthru a Powershell variable to the cmd.exe interpreter. Be interesting to next see if I can reverse the process.
# writes out time and date from cmd.exe
write "Time and Date from CMD.EXE:"
$Global:command =
"time /t",
"date /t"
out-file -inputobject $command -encoding ASCII -filepath $pwd\cmd.txt
Start-Process cmd.exe -argument /Q -nonewwindow -wait -redirectstandardinput $pwd\cmd.txt
Subscribe to:
Posts (Atom)