Friday, December 22, 2006

Powershell Network Scan - Script

Here's the code/script for network scan I was talking about in previous post here


function HandleShare
{
$share = $args[0];
write-host ***Scanning Share $share
#write-host net use X: $share
$erroractionpreference = "SilentlyContinue";
$files = Get-ChildItem -recurse -name $share $fileType
$erroractionpreference = "Continue";

foreach($file in $files)
{
if($file.length -gt 0)
{
$filepath = $share + "\" + $file;
write-host $filepath
}
}

}

function HandleHost
{
$hostname = $args[0];
$hostname = $hostname.substring(0, $hostname.indexof(" "))
#write-host "***Scanning Host " + $hostname;

#List shares.
$shares = net view $hostname | findstr " Disk"
foreach($share in $shares)
{
if($share.length -gt 0)
{
$tmp = $share.substring(0, $share.indexof("Disk"));
$tmp = $tmp.Trim();
$tmp = $hostname + "\" + $tmp;
HandleShare $tmp;
}
}
}

function DisplayUsage
{
write-host
write-host -foregroundcolor green "Usage:"
write-host -foregroundcolor green " scan.ps1 fileType maxNoOfMachines"
write-host -foregroundcolor green " e.g. scan.ps1 *.txt 10"
write-host
}

function Main
{
$hostnames = net view | findstr "\\";
foreach($hostname in $hostnames)
{
$maxNoOfMachines = $maxNoOfMachines - 1;
if($maxNoOfMachines -lt 0)
{
exit;
}

HandleHost $hostname;
}
}

#
# Initialise
#

#Guard against un initialised variables. aka, typos
set-psdebug –strict

#using $fluff as i dint like LoadWithPartialName o/p somethign to console.
$fluff = [reflection.assembly]::LoadWithPartialName("'Microsoft.VisualBasic")

#
# Validate input paramters
#
if($args.count -lt 2 -or $args.count -gt 2)
{
DisplayUsage;
exit;
}
if(-not([Microsoft.VisualBasic.Information]::isnumeric($args[1])))
{
DisplayUsage;
write-host -foregroundcolor Red "Error:"
write-host -foregroundcolor Red " Second paramter should be numeric."
write-host
exit;
}

#
# Convert args into variables which are used through out this script.
#

$maxNoOfMachines = $args[1];
$fileType = $args[0]; #Global variable used in HandleShare.
#$maxNoOfMachines = 30; #Global variable used in Main.

#
# Start actual work
#

Main;

1 comment:

Jeffrey Snover said...

Cool stuff!

Did you consider using PARAM? It could save you a bunch of work. PARAM needs to be the first EXECUTABLE statement in your script (it can have comments before it). The nice things about param are
1) self-documention
2) you can provide a TYPE for the variables and PS will do the work or generate the error message for you (the message will be the standard one for that error).
3) you can provide an initial value.
4) it allows POSITIONAL or NAMED parameter invocation.
Boy, with all that, how can you resist? :-)

Try the following and see if you like it:

PARAM([string]$fileType="*.mp3", [int]$maxNoMachines=30)

From there you can then invoke it the following ways (all of the following produce the same results):
scan1 *.mp3 30
scan1 -FileType *.mp3 -count 30
scan1 -count 30 -FileType *.mp3
scan1 *.mp3
scan1


The other thing to consider is -= :

$maxNoOfMachines -= 1;

Have a great holiday!
Cheers!

Jeffrey Snover [MSFT]
Windows PowerShell/MMC Architect
Visit the Windows PowerShell Team blog at: http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at: http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx



PARAM(