I have DHCP script that looks for matching hostnames in all the scopes on the DHCP servers
$list = Get-Content C:\script\HostNameList.txt #Defines content it pulls as list
$DHServers = Get-DhcpServerInDC #gives variable name for loop
# Gets all DHCP servers ands scopes
foreach ($Server in $DHServers){
$scopes = Get-DHCPServerv4Scope -ComputerName $Server.dnsname #get all scopes
}
$Output = foreach ($hostname in $list) { #Calls each item in list a hostname and sends to output
if (test-connection -count 1 -computername $hostname -quiet) #With 1 ping, check if hostname is online
{
foreach ($scope in $scopes){
if($scope | Get-DhcpServerV4Lease -ComputerName $server.dnsname | Where-Object HostName -like "$hostName*" ) #compares the hostname to lease to find which scope it is in
{ $scope.name } #return scope it found hostname in
}
[PSCustomObject]@{ #Rename varibles in data pull for output file
Asset = $hostname
Location = $scope.name #only want the name of the scope
Status = "Online"
}
}
else #statement if hostname is not online
{
Write-host "$hostname Is offline, only Last Location is known. $hostname was added to the output file." -BackgroundColor DarkRed
[PSCustomObject]@{
Asset = $hostname
Location = $scope.name #only want the name of the scope, since the name = Location
Status = "Offline"
}
}
}
$Output #show output in powershell
$Output | Export-Csv -Path C:\script\Asset_Result.csv -NoTypeInformation #outputs .csv
Asset Location Status
----- -------- ------
A847 Public Internet Online
A261 Public Internet Offline
A201 Public Internet Online
Asset Location Status
----- -------- ------
A847 FLoor 1 Online
A261 West 1st FL Offline
A201 Floor 3 Online
How can I get $scope.name
in my
if($scope | ...
statement to go to my PSCustomObject after each iteration?
This:
foreach ($Server in $DHServers){
$scopes = Get-DHCPServerv4Scope -ComputerName $Server.dnsname #get all scopes
}
is - in net effect - the equivalent of:
$scopes = Get-DHCPServerv4Scope -ComputerName $DHServers[-1].dnsname #get all scopes
That is, you keep reassigning to the same variable ($scopes
) in the loop body, replacing the previous value, so that you end up with only the result from the last loop iteration, for the last server stored in $DHServers
, i.e. $DHServers[-1]
.
The best solution is to rely on PowerShell's ability to use statements such as foreach
as an expression whose output - even iterative output from a loop - is automatically collected in an [object[]]
array (with two or more outputs) by PowerShell:
# Collect the output from *all* Get-DHCPServerv4Scope calls.
[array] $scopes = foreach ($Server in $DHServers) {
Get-DHCPServerv4Scope -ComputerName $Server.dnsname #get all scopes
}
Note: The [array]
type constraint (same as: [object[]]
) is only necessary if there can situationally be just one output object and you want to ensure that the collected output is always an array.