﻿# encoding: utf-8
# api: powershell
# title: Invoke-Command on subnet
# description: This script pingscan a subnet for running machines (full parallel) and executes (full parallel) any command on these machines
# version: 0.1
# type: script
# author: Carsten Krueger
# license: CC0
# function: Get-IPAddress
# x-poshcode-id: 2705
# x-archived: 2011-06-06T03:22:46
# x-published: 2011-06-02T13:57:00
#
#
$secpasswd = ConvertTo-SecureString "here the password" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential ("Administrator@domain", $secpasswd)

$subnet="192.168.0." 
$hosts=( New-IPRange -start ($subnet + 1) -end ($subnet + 255) | Test-Online | Get-HostName | ForEach-Object { $_.HostName.ToString() } )
$hosts

Invoke-Command  -ComputerName $hosts -Credential $mycreds -ScriptBlock {
	Write-host "Starting on host"$env:computername
	dir
	# Start-Process -wait myCommand
}

# ---------------------------- needed functions ---------------------------
#http://powershell.com/cs/blogs/tobias/archive/2011/03/09/analyzing-networks-with-powershell.aspx

function Get-IPAddress {
	# created by Dr. Tobias Weltner, MVP PowerShell

	param(
		[switch]
		$first,
		[Parameter(ParameterSetName='IPV4')]
		[switch]
		$IPv4,
		[Parameter(ParameterSetName='IPV4')]
		[switch]
		$IPv6
	)
	$ip = @(Get-WmiObject -Filter 'IPEnabled=true' Win32_NetworkAdapterConfiguration | Select-Object -ExpandProperty IPAddress)
	if ($IPv4) { $ip = $ip | Where-Object { $_ -like '*.*' }}
	if ($IPv6) { $ip = $ip | Where-Object { $_ -like '*:*' }}

	if ($ip.Count -gt 1 -and $first) {
		$ip[0]
	} else {
		$ip
	}
}


function New-IPRange {
	# created by Dr. Tobias Weltner, MVP PowerShell

	[CmdletBinding(DefaultParameterSetName='Automatic')]
	param(
		[Parameter(ParameterSetName='Manual')]
		[String]
		$start, 
		[Parameter(ParameterSetName='Manual')]
		[String]
		$end,
		[Parameter(ParameterSetName='Automatic')]
		[switch]
		$first
	)


	function Get-IPRange($start, $end) {
		$ip1 = ([System.Net.IPAddress]$start).GetAddressBytes()
		[Array]::Reverse($ip1)
		$ip1 = ([System.Net.IPAddress]($ip1 -join '.')).Address
	
		$ip2 = ([System.Net.IPAddress]$end).GetAddressBytes()
		[Array]::Reverse($ip2)
		$ip2 = ([System.Net.IPAddress]($ip2 -join '.')).Address
	
		for ($x = $ip1; $x -le $ip2; $x++) {
			$ip = ([System.Net.IPAddress]$x).GetAddressBytes()
			[Array]::Reverse($ip)
			$ip -join '.'
		}
	
	}
	
	if ($PSCmdlet.ParameterSetName -eq 'Automatic') {
		@(Get-IPAddress -first:$first -IPv4) |
		ForEach-Object {
			$temp = ([System.Net.IPAddress]$_).GetAddressBytes()
			$temp[3] = 1
			[System.Net.IPAddress]$start = $temp -join '.'
			$temp[3] = 255
			[System.Net.IPAddress]$end = $temp -join '.'
			Get-IPRange $start $end		
		}
	} else {
		Get-IPRange $start $end
	}	
}

function Test-Online {
	# created by Dr. Tobias Weltner, MVP PowerShell

	param(
		[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
		[String]
		$computername,
		[Int32]
		$throttleLimit = 300
	)

	begin { $list = New-Object System.Collections.ArrayList }
	process { 
		[void]$list.Add($computername)
	}
	end {
		& { 
			do {
			$number = [Math]::Min($list.Count, $throttleLimit)
			$chunk = $list.GetRange(0, $number)
			
			$job = Test-Connection $chunk �Count 1 �asJob
			$job | Wait-Job | Receive-Job | Where-Object { $_.StatusCode �eq 0 } | Select-Object �expandProperty Address 
			Remove-Job $job
			$list.RemoveRange(0, $number)
		} while ($list.Count -gt 0) 
		} | Sort-Object { [System.Version]$_ }
	}

}

function Get-HostName {
	# created by Dr. Tobias Weltner, MVP PowerShell

	param(
		[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
		[String[]]
		$IPAddress
	)

	process {
		$IPAddress | Foreach-Object {
			$ip = $_
			try {
				[System.Net.DNS]::GetHostByAddress($ip)
			} catch { 
				Write-Warning �IP $ip did not return DNS information�
			}
		}
	}
}


#New-IPRange | Test-Online | Get-HostName
