Powershell - Local Network scan (no domain) - powershell

Just wondering if anybody knows a way in powershell to scan the local network for Computers, resolving their name's and IP's.
I know a possibility with Get-ADComputer, but this network is not in a domain.

You can use the .net DNS class in powershell.
reference: http://msdn.microsoft.com/en-us/library/system.net.dns%28v=vs.110%29.aspx
example:
PS C:\> $dns = [system.net.dns]
PS C:\> $dns::GetHostEntry("198.252.206.16") | format-list
HostName : stackoverflow.com
Aliases : {}
AddressList : {198.252.206.16}
Scanning example if your network as a 192.168.1.0/24:
$results = #() ; 1..255 | % { $results += $dns::GetHostByAddress("192.168.1.$_") }

Related

how to format Powershell output in specific way?

I need to scan my network for specific processes on servers. I've done this script:
28..31 | ForEach-Object { Get-Process -ComputerName "192.168.0.$_" -Name svc* }
Now how can I format output so it shows on which IP address found process shown? Thank you.
I suggest switching to PowerShell's remoting, because:
it provides a framework for executing any command remotely - rather than relying on individual cmdlets to support a -ComputerName parameter and uses a firewall-friendly transport.
it will continue to be supported in PowerShell [Core] v6+, where the cmdlet-individual -ComputerName parameters aren't supported anymore; this obsolete remoting method uses an older, less firewall-friendly form of remoting that the - obsolete since v3 - WMI cmdlets also use (the latter were replaced by the CIM cmdlets).
It is therefore better to consistently use the firewall-friendly PowerShell remoting with its generic remoting commands (Invoke-Command, Enter-PSSession, ...).
If you use Invoke-Command to target (multiple) remote computers, the objects returned automatically contain and display the name of the originating computer, via the automatically added .PSComputerName property:
# Create the array of IP addresses to target:
$ips = 28..31 -replace '^', '192.168.0.'
# Use a *single* Invoke-Command call to target *all* computers at once.
# Note: The results will typically *not* reflect the input order of
# given IPs / computer names.
Invoke-Command -ComputerName $ips { Get-Process -Name svc* }
You'll see output such as the following - note the PSComputerName column:
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName PSComputerName
------- ------ ----- ----- ------ -- -- ----------- --------------
1013 18 7464 13732 52.72 8 0 svchost 192.168.0.30
...
Note that you can suppress automatic display of the .PSComputerName property with Invoke-Command's -HideComputerName parameter.
However, the property is still available programmatically, which allows you to do the following:
Invoke-Command -ComputerName $ips { Get-Process -Name svc* } -HideComputerName |
Format-Table -GroupBy PSComputerName
This yields display output grouped by computer name / IP:
PSComputerName: 192.168.0.30
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
1013 18 7464 13732 52.72 8 0 svchost
...
PSComputerName: 192.168.0.28
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
1007 17 7112 12632 65.45 11 0 svchost
...
If you wanted to sort by IP address before grouping, you could insert | Sort-Object { [version] $_.PSComputerName }[1] before the Format-Table call.
For sorting by computer names, just
| Sort-Object PSComputerName would do.
[1] Casting to [version] is a trick to ensure proper sorting of IP addresses; IP address strings can be interpreted as [version] (System.Version) instances, and such instances are directly comparable, using the numeric values of the version components (first by .MajorVersion, then by .MinorVersion, ...)
here's one way to do the job. [grin] what it does ...
builds the ip final octet range
sets the IPv4 base octets
builds the list of processes to search for
sets the "no response" text
iterates thru the 4th octet range
builds the IPv4 address
checks to see if it is online/responding
if so, gets the hostname
for my version of PoSh [win7, ps5.1] the Get-Process cmdlet will NOT accept an ip address. a hostname is required.
corrects for the damaged hostname returned when one uses ATT for inet service
creates an ordered hashtable to use for building the property list
builds the various props as needed
converts the hashtable to a PSCustomObject
sends that to the $Results collection
shows it on screen
sends it to a CSV file
here's the code ...
$4thOctetRange = 64..66
$IpBase = '192.168.1'
$ProcessList = #(
'AutoHotKey'
'BetterNotBeThere'
'DisplayFusion'
'Foobar2000'
)
$NoResponse = '__n/a__'
$Results = foreach ($4OR_Item in $4thOctetRange)
{
$Ip = '{0}.{1}' -f $IpBase, $4OR_Item
$Online = Test-Connection -ComputerName $Ip -Count 1 -Quiet
if ($Online)
{
# getting the hostname is REQUIRED by my version of Get-Process
# it will not accept an IP address
# version info = win7, ps5.1
# this may need adjusting for your returned hostname
# mine shows Hostname.attlocal.net
# that is not valid with any query i make, so i removed all after the 1st dot
$HostName = ([System.Net.Dns]::GetHostByAddress($Ip)).HostName.Split('.')[0]
}
else
{
$HostName = $NoResponse
}
$TempProps = [ordered]#{}
$TempProps.Add('IpAddress', $Ip)
$TempProps.Add('Online', $Online)
$TempProps.Add('HostName', $HostName)
foreach ($PL_Item in $ProcessList)
{
if ($TempProps['Online'])
{
# if the process aint found, the "SilentlyContinue" forces a $Null
# the "[bool]" then coerces that to a "False"
$TempProps.Add($PL_Item, [bool](Get-Process -ComputerName $HostName -Name $PL_Item -ErrorAction SilentlyContinue))
}
else
{
$TempProps.Add($PL_Item, $NoResponse)
}
}
# send the object out to the $Results collection
[PSCustomObject]$TempProps
}
# send to screen
$Results
# send to CSV file
$Results |
Export-Csv -LiteralPath "$env:TEMP\Senator14_RemoteProcessFinder.csv" -NoTypeInformation
truncated screen output ...
IpAddress : 192.168.1.65
Online : True
HostName : ZK_01
AutoHotKey : True
BetterNotBeThere : False
DisplayFusion : True
Foobar2000 : True
IpAddress : 192.168.1.66
Online : False
HostName : __n/a__
AutoHotKey : __n/a__
BetterNotBeThere : __n/a__
DisplayFusion : __n/a__
Foobar2000 : __n/a__
csv file content ...
"IpAddress","Online","HostName","AutoHotKey","BetterNotBeThere","DisplayFusion","Foobar2000"
"192.168.1.64","False","__n/a__","__n/a__","__n/a__","__n/a__","__n/a__"
"192.168.1.65","True","ZK_01","True","False","True","True"
"192.168.1.66","False","__n/a__","__n/a__","__n/a__","__n/a__","__n/a__"

How to get EC2 Instances IpAddress of a cloudformation stack using PowerShell?

I want to list down IpAddresses of EC2 Instances of a CloudFormation stack using PowerShell. I'm trying the below command but it is not returning IpAddress.
Get-CFNStackResourceList -StackName 'teststack' -LogicalResourceId 'EC2Instance' -region 'eu-west-1'
I suggest to check with
Get-EC2InstanceStatus (AWS Tools for Windows PowerShell)
or DescribeInstanceStatus (Amazon EC2 Query API)
Basic example:
PS C:\> Get-EC2InstanceStatus -InstanceId i-12345678
AvailabilityZone : us-west-2a
Events : {}
InstanceId : i-12345678
InstanceState : Amazon.EC2.Model.InstanceState
Status : Amazon.EC2.Model.InstanceStatusSummary
SystemStatus : Amazon.EC2.Model.InstanceStatusSummary
PS C:\> $status = Get-EC2InstanceStatus -InstanceId i-12345678
PS C:\> $status.InstanceState
Code Name
---- ----
16 running
Then, collect all IPv4 addresses like this:
$EC2Instances = Get-EC2Instance
foreach($instance in $EC2Instances.Instances){
$addresses = "";
foreach($networkInterface in $instance.NetworkInterfaces){
$addresses = $addresses, $networkInterface.PrivateIpAddresses.PrivateIpAddress -join ","
}
"$($instance.InstanceID): $($addresses.Trim(','))"
}
Furthermore, it might be helpful to count the instances like this:
$filterRunning = New-Object Amazon.EC2.Model.Filter -Property #{Name = "instance-state-name"; Value = "running"}
$runningInstances = #(Get-EC2Instance -Filter $filterRunning)
# Count the running instances
$runningInstances.Count
See also: AWS Developer Blog - Scripting your EC2 Windows fleet using Windows PowerShell and Windows Remote Management

How to verify whether a windows server has mountpoint or not using WMI

I am generating a report where I need to find which servers has mountpoints configured on it..
can you help how to get that infor using WMI or powershell.
I mean I need to identify the servers, if mountpoints exists in it.. and also their names....
Get a list of all servers from textfile, AD, etc. and run a foreach loop with something like this:
Get-Wmiobject -query “select name,driveletter,freespace from win32_volume where drivetype=3 AND driveletter=NULL” -computer servername
A quick google search for "windows mount point wmi" would return THIS (source).
Then export the results to CSV, HTML or whatever you need. Your question is lacking a lot of details and any sign of effort from your part, so I can't/won't go any further.
UPDATE: Does this help? It lists mount points(folder paths, not driveletters).
$servers = #("server1","server2","server3","server4","server5")
$servers | % {
$mountpoints = #(Get-WmiObject Win32_MountPoint -ComputerName $_ | Select-Object -ExpandProperty Directory | ? { $_ -match 'Win32_Directory.Name="(\w:\\\\.+)"' }) | % { [regex]::Match($_,'Win32_Directory.Name="(\w:\\\\.+)"').Groups[1].Value -replace '\\\\', '\' }
if($mountpoints.Count -gt 0) {
New-Object psobject -Property #{
Server = $_
MountPoints = $mountpoints
}
}
}
Server MountPoints
------ -----------
{server1} {D:\SSD, C:\Test}

Resolving IP Address from hostname with PowerShell

I am trying to get the ipaddress from a hostname using Powershell, but I really can't figure out how.
Any help?
You can get all the IP addresses with GetHostAddresses like this:
$ips = [System.Net.Dns]::GetHostAddresses("yourhosthere")
You can iterate over them like so:
[System.Net.Dns]::GetHostAddresses("yourhosthere") | foreach {echo $_.IPAddressToString }
A server may have more than one IP, so this will return an array of IPs.
this is nice and simple and gets all the nodes.
$ip = Resolve-DNSName google.com
$ip
also try inputting an ip instead of a domain name and check out those results too!
Use Resolve-DnsName cmdlet.
Resolve-DnsName computername | FT Name, IPAddress -HideTableHeaders | Out-File -Append c:\filename.txt
PS C:\> Resolve-DnsName stackoverflow.com
Name Type TTL Section IPAddress
---- ---- --- ------- ---------
stackoverflow.com A 130 Answer 151.101.65.69
stackoverflow.com A 130 Answer 151.101.129.69
stackoverflow.com A 130 Answer 151.101.193.69
stackoverflow.com A 130 Answer 151.101.1.69
PS C:\> Resolve-DnsName stackoverflow.com | Format-Table Name, IPAddress -HideTableHeaders
stackoverflow.com 151.101.65.69
stackoverflow.com 151.101.1.69
stackoverflow.com 151.101.193.69
stackoverflow.com 151.101.129.69
PS C:\> Resolve-DnsName -Type A google.com
Name Type TTL Section IPAddress
---- ---- --- ------- ---------
google.com A 16 Answer 216.58.193.78
PS C:\> Resolve-DnsName -Type AAAA google.com
Name Type TTL Section IPAddress
---- ---- --- ------- ---------
google.com AAAA 223 Answer 2607:f8b0:400e:c04::64
You could use vcsjones's solution, but this might cause problems with further ping/tracert commands, since the result is an array of addresses and you need only one.
To select the proper address, Send an ICMP echo request and read the Address property of the echo reply:
$ping = New-Object System.Net.NetworkInformation.Ping
$ip = $($ping.Send("yourhosthere").Address).IPAddressToString
Though the remarks from the documentation say:
The Address returned by any of the Send overloads can originate from a malicious remote computer. Do not connect to the remote computer using this address. Use DNS to determine the IP address of the machine to which you want to connect.
Working one liner if you want a single result from the collection:
$ipAddy = [System.Net.Dns]::GetHostAddresses("yahoo.com")[0].IPAddressToString;
hth
If you know part of the subnet (i.e. 10.3 in this example), then this will grab any addresses that are in the given subnet:
PS C:\> [System.Net.Dns]::GetHostAddresses("MyPC") | foreach { $_.IPAddressToString | findstr "10.3."}
This worked well for my purpose
$ping = ping -4 $env:COMPUTERNAME
$ip = $ping.Item(2)
$ip = $ip.Substring(11,11)
$computername = $env:computername
[System.Net.Dns]::GetHostAddresses($computername) | where {$_.AddressFamily -notlike "InterNetworkV6"} | foreach {echo $_.IPAddressToString }
The Test-Connection command seems to be a useful alternative, and it can either provide either a Win32_PingStatus object, or a boolean value.
Documentation:
https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.management/test-connection
You can use this code if you have a bunch of hosts in text file
$a = get-content "C:\Users\host.txt"(file path)
foreach ($i in $a )
{
$i + "`n" + "==========================";[System.Net.Dns]::GetHostAddresses($i)
}
The simplest way:
ping hostname
e.g.
ping dynlab938.meng.auth.gr
it will print:
Pinging dynlab938.meng.auth.gr [155.207.29.38] with 32 bytes of data
try
$address = 'HOST NAME'
Resolve-DnsName $address | Select-Object Name, IPAddress | Export-csv "C:\Temp\CompleteNSLookup.csv" -append -NoType

NetBIOS domain of computer in PowerShell

How can I get the NetBIOS (aka 'short') domain name of the current computer from PowerShell?
$ENV:USERDOMAIN displays the domain of the current user, but I want the domain that the current machine is a member of.
I've discovered you can do it pretty easily in VBScript, but apparently ADSystemInfo isn't very nice to use in PowerShell.
Update
Here's my final solution incorporating the suggestion of using Win32_NTDomain, but filtering to the current machine's domain
$wmiDomain = Get-WmiObject Win32_NTDomain -Filter "DnsForestName = '$( (Get-WmiObject Win32_ComputerSystem).Domain)'"
$domain = $wmiDomain.DomainName
In most cases, the default NetBIOS domain name is the leftmost label in the DNS domain name up to the first 15 bytes (NetBIOS names have a limit of 15 bytes).
The NetBIOS domain name may be changed during the installation of the Active Directory, but it cannot be changed.
The WIN32_ComputerSystem WMI object gives informations on a Windows computer
PS C:\> Get-WmiObject Win32_ComputerSystem
Domain : WORKGROUP
Manufacturer : Hewlett-Packard
Model : HP EliteBook 8530w (XXXXXXXXX)
Name : ABCHPP2
PrimaryOwnerName : ABC
TotalPhysicalMemory : 4190388224
So the domain Name is given by :
PS C:\> (gwmi WIN32_ComputerSystem).Domain
But in domain installation, the DNS name is given. In this case, you can use nbtstat -n command to find the NetBIOS domain name which is displayed like this <DOMAIN><1B>.
The PowerShell Command may be :
nbtstat -n | Select-String -Pattern "^ *(.*) *<1B>.*$" | % {$_ -replace '^ *(.*) *<1B>.*$','$1'}
Here is another way using WMI
PS C:\> (gwmi Win32_NTDomain).DomainName
Use env: to get environment settings through PowerShell
NetBIOS: $env:userdomain
FQDN: $env:userdnsdomain
To see all the values:
dir env: (no $)
import-module activedirectory
(Get-ADDomain -Identity (Get-WmiObject Win32_ComputerSystem).Domain).NetBIOSName
From Here
# Retrieve Distinguished Name of current domain.
$Domain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()
$Root = $Domain.GetDirectoryEntry()
$Base = ($Root.distinguishedName)
# Use the NameTranslate object.
$objTrans = New-Object -comObject "NameTranslate"
$objNT = $objTrans.GetType()
# Invoke the Init method to Initialize NameTranslate by locating
# the Global Catalog. Note the constant 3 is ADS_NAME_INITTYPE_GC.
$objNT.InvokeMember("Init", "InvokeMethod", $Null, $objTrans, (3, $Null))
# Use the Set method to specify the Distinguished Name of the current domain.
# Note the constant 1 is ADS_NAME_TYPE_1779.
$objNT.InvokeMember("Set", "InvokeMethod", $Null, $objTrans, (1, "$Base"))
# Use the Get method to retrieve the NetBIOS name of the current domain.
# Note the constant 3 is ADS_NAME_TYPE_NT4.
# The value retrieved includes a trailing backslash.
$strDomain = $objNT.InvokeMember("Get", "InvokeMethod", $Null, $objTrans, 3)
OP is after "computer domain" so the answer would be $GetComputerDomain (below) but I will add the $GetUserDomain also for reference.
$GetComputerDomain = ([System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain()).Name
$GetUserDomain = ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).Name
I find the wmi (gwmi) option to be extremely slow, especially, when you are querying the Win32_NTDomain class. I have a multi-trusted domain environment and it takes forever when I just need that simple info quick.
Use the Active Directory Cmdlet Get-ADDomain:
(Get-ADDomain -Current LocalComputer).NetBIOSName
The below powershell command works great! I tested after trying various solutions.
If you use the following .Net command:
[System.Net.Dns]::GetHostByAddress('192.168.1.101').hostname
It works too, but it is using DNS to resolve, in my case, we have WINS setup to support an application that requires it, so can't use it. Below is what I ended up using as part of a script I use to check for WINS registration for each client:
$IPAddress = "<enterIPAddress>" (remove brackets, just enter IP address)
(nbtstat -A $IPAddress | ?{$_ -match '\<00\> UNIQUE'}).Split()[4]
http://social.technet.microsoft.com/Forums/en-US/f52eb2c7-d55d-4d31-ab4e-09d65d366771/how-to-process-cmd-nbtstat-a-ipaddress-output-and-display-the-computer-name-in-powershell?forum=ITCG
The above link has the thread and conversation.
Using NetGetJoinInformation and P/Invoke:
Add-Type -MemberDefinition #"
[DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern uint NetApiBufferFree(IntPtr Buffer);
[DllImport("netapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern int NetGetJoinInformation(
string server,
out IntPtr NameBuffer,
out int BufferType);
"# -Namespace Win32Api -Name NetApi32
function GetDomainName {
$pNameBuffer = [IntPtr]::Zero
$joinStatus = 0
$apiResult = [Win32Api.NetApi32]::NetGetJoinInformation(
$null, # lpServer
[Ref] $pNameBuffer, # lpNameBuffer
[Ref] $joinStatus # BufferType
)
if ( $apiResult -eq 0 ) {
[Runtime.InteropServices.Marshal]::PtrToStringAuto($pNameBuffer)
[Void] [Win32Api.NetApi32]::NetApiBufferFree($pNameBuffer)
}
}
This can also be done by using .NET framework (which is much faster than WMI)
PS > [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
Will return
HostName : SurfaceBook
DomainName : mydomain.com
NodeType : Hybrid
DhcpScopeName :
IsWinsProxy : False
Using the ADSystemInfo COM object should work, with no delay from Win32_NTDomain lookup:
$ADSystemInfo = New-Object -ComObject "ADSystemInfo"
$ADSystemInfo.GetType().InvokeMember("DomainShortName", "GetProperty", $null, $ADSystemInfo, $null)
There are other AD-related properties available from this COM object too:
https://learn.microsoft.com/en-us/windows/win32/adsi/iadsadsysteminfo-property-methods
[EDITED - Originally included code for the WinNTSystemInfo COM object instead but a commenter pointed out this only returns the user's short domain - but ADSystemInfo does return the computer's short domain]
Here is another faster method than Win32_NTDomain, for getting the NetBIOS domain of the computer.
# Get the computer system CIM/WMI
$computersystem = Get-CimInstance Win32_ComputerSystem
# Create a Windows Identity Principal object based on the name and domain in Win32_ComputerSystem
$ComputerPrincipal = [System.Security.Principal.WindowsIdentity]::new("$($computersystem.name)#$($computersystem.domain)")
# Split the NetBIOS name on \ and get the first value which should be the domain
($ComputerPrincipal.Name -split "\\")[0]
# Bonus point, the WindowsIdentity Principal has a bunch of other useful information.
# Like quick enumeration of the groups it's in (but needs to be translated from SID to NTAccount format).
$ComputerPrincipal.Groups.Translate([System.Security.Principal.NTAccount]).value