1

I essentially have an array $ServerList which holds a list of array I want to test, while $ExclusionList is a list of servers that have to be exluded.

The code should test the list of server with a Test-Connection and save the unreachable ones in $nonactivearray and remove them from $ServerList. After that it will remove any entry in $ExclusionList from $ServerList.

If $ServerList becomes and empty array, it will ask the user to type the list of servers.

The code seems to work correctly until a correct server is given. I found that, although $nonactivearray becomes empty, $nonactivearray.Count or $nonactivearray.Length return 1, hence it will enter in a endless loop since both $ServerList and $nonactivearray have number of elements greater than 0.

# Define function to center the text in the current line (taken from: https://stackoverflow.com/a/48622585/10516690)
function Write-HostCenter {
    param($Message)
    Write-Host ("{0}{1}" -f (' ' * (([Math]::Max(0, $Host.UI.RawUI.BufferSize.Width / 2) - [Math]::Floor($Message.Length / 2)))), $Message)
}

# Define Test-Connection as a string for Invoke-Expression later
[string]$TestConn = "Test-Connection -Quiet -Count 1 -ComputerName "

# Define excluded servers
$ExclusionList = @("Server1","Server2","Server3")

# Save old progress settings
$OldProgress = $ProgressPreference
$ProgressPreference = 'SilentlyContinue'

# Test Server availability
$nonactivearray = @() # Array of unreachable/excluded servers
$nonactive = "" # String to display the unreachable/excluded doscovered in our list of servers. Probably unnecessary, "$nonactivearray" can be used
$i = 0
foreach ($newserver in $ServerList) {
    if (-Not (Invoke-Expression -Command "$TestConn $newserver")) {
        $nonactive += $newserver
        $nonactivearray += $newserver
        if ($i -lt $ServerList.Length) {
            $nonactive += " "
        }
    }
    $i++
}
$ProgressPreference = $OldProgress

# List unreachable and excluded servers
$nonactivearray += (Compare-Object -ReferenceObject $ServerList `
                        -DifferenceObject $ExclusionList `
                        -ExcludeDifferent -IncludeEqual).InputObject
$nonactive = "$nonactivearray"
$CurPosPing = $host.UI.RawUI.CursorPosition
while ($nonactivearray.Length -ge 1) {
    $host.UI.RawUI.CursorPosition = $CurPosPing
    Write-Host "  These HOSTS are not reachable, hence they will be ignored:"
    $TempForegroundColor = $Host.Ui.RawUI.ForegroundColor  # <== Temporary solution
    $Host.Ui.RawUI.ForegroundColor = "Red"                 # <== Temporary solution
    Write-HostCenter $nonactive                            # Write-HostCenter defined in a function. It centers the text in the shell
    $Host.Ui.RawUI.ForegroundColor = $TempForegroundColor  # <== Temporary solution

    # Remove unreachable servers with filters
    $ServerList = $ServerList | Where-Object {$nonactivearray -notcontains $_}

    # Check if the new list is empty
    while ($ServerList.Length -lt 1) {
        Write-Host " "
        $CurPos = $host.UI.RawUI.CursorPosition
        Write-Host "  The list of server is now empty, please type it now.    " -ForegroundColor Yellow
        Write-Host "  Use the comma `"" -NoNewline; Write-Host "," -NoNewline -ForegroundColor Yellow
        Write-Host "`" as a separator (spaces will be ignored)."
        Write-Host " "
        # Get list from user
        # $CurPos = $host.UI.RawUI.CursorPosition
        $ServerList = Read-Host -Prompt "  Server list"
        $ServerList = $ServerList -replace ' ',''
        [string[]]$ServerList = $ServerList -split ','
        $ServerList = $ServerList | Where-Object {$_.length -gt 0}
        while ($ServerList.Length -lt 1) {
            $Host.UI.RawUI.CursorPosition = $CurPos
            Write-Host "  >>> The list is STILL empty, please type it again. <<<      " -ForegroundColor Yellow
            Write-Host " "
            Write-Host " "
            # $CurPos = $host.UI.RawUI.CursorPosition
            $ServerList = Read-Host -Prompt "  Server list"
            $ServerList = $ServerList -replace ' ', ''
            [string[]]$ServerList = $ServerList -split ','
            $ServerList = $ServerList | Where-Object {$_.length -gt 0}
        }
    }
    # Re-check server connectivity
    $OldProgress = $ProgressPreference
    $ProgressPreference = 'SilentlyContinue'
    Write-Host "serverlist"
    $ServerList
    $nonactivearray = @()
    $nonactive = ""
    $i = 0
    foreach ($newserver in $ServerList) {
        if (-Not (Invoke-Expression -Command "$TestConn $newserver")) {
            $nonactive += $newserver
            $nonactivearray += $newserver
            if ($i -lt $ServerList.Length) {
                $nonactive += " "
            }
        }
        $i++
    }
    $ProgressPreference = $OldProgress
    $nonactivearray += (Compare-Object -ReferenceObject $ServerList `
                            -DifferenceObject $ExclusionList `
                            -ExcludeDifferent -IncludeEqual).InputObject
    $nonactive = "$nonactivearray"
}

Thank you and best.

[EDIT]

Sorry, I also forgot the following lines that I have added on the top of the code:

# Define function to center the text in the current line (taken from: https://stackoverflow.com/a/48622585/10516690)
function Write-HostCenter {
    param($Message)
    Write-Host ("{0}{1}" -f (' ' * (([Math]::Max(0, $Host.UI.RawUI.BufferSize.Width / 2) - [Math]::Floor($Message.Length / 2)))), $Message)
}

# Define Test-Connection as a string for Invoke-Expression later
[string]$TestConn = "Test-Connection -Quiet -Count 1 -ComputerName "

# Define excluded servers
$ExclusionList = @("Server1","Server2","Server3")

I hope I am not forgetting anything else...

Danilo
  • 29
  • 5
  • If `Count` returns "1" then it's not empty. I suppose you add a null value to it. Maybe try `$nonactivearray = (Compare-Object ...` instead of `+=` – marsze Oct 17 '18 at 10:28
  • To avoid that `$nonactivearray` has a single object (which will usually be flattened by PowerShell to just an object) that has a `Count` or a `Lenght` property itself, use: `@($nonactivearray).Count` to force is the use the `Count` property of a/the array. – iRon Oct 17 '18 at 11:03
  • 1
    In general, I recommend you to create an [mcve] which will likely help you to resolve this yourself or/and get more response. – iRon Oct 17 '18 at 11:25

1 Answers1

1

Thank you for your help. I could not fix the issue with the solutions proposed, but you gave me the insight to find a solution. I searched for "how to remove $null values from an array" and I found this answer from mklement0 in another post.

I tried the following:

PS N:\> $list = @("1","","3","$null","7")
PS N:\> $list
1

3

7
PS N:\> $list -notlike ''
1
3
7

and then added the following line in my code:

$nonactivearray = $nonactivearray -notlike ''

That solved the issue. :)

Thank you again.

Danilo
  • 29
  • 5