PowerCLI

 View Only
Expand all | Collapse all

ESXi Host EOL report

  • 1.  ESXi Host EOL report

    Posted Jan 29, 2020 11:27 AM

    Hi All,

    I've created the below to generate a report containing End of Life / End of Support information for approx 2000 ESXi Hosts, spread across multiple vCenters.

    The report works to a point. I've just noticed that it's returning the same Serial numbers for a lot of the ESXi Hosts, these should all be unique. I've also noticed that the model numbers are not always correct either. If i run the script against individual ESXi Hosts, the data returned is correct.

    The script runs without error so i don't understand why duplicate/incorrect information is being returned for some of the Servers.

    Could it be that i don't have enough memory/cpu on the server that's running the script ?

    Should i be using Get-View instead of Get-Esxcli to optimize the data collection ?

    Should i be setting each variable to null before moving to the next ESXi Host (seems wasteful)

    $cred = Get-Credential 'username@company.com'

    $vCenters = @(

        "vc1.company.com"

        "vc2.company.com"

        "vc3.company.com"

        "vc4.company.com"

        )

    Connect-VIServer -Server $vCenters -Credential $cred -ErrorAction SilentlyContinue

    # Server model to EOL date mappings, edit to add/correct dates

    $vmHostModelEolMapping = @{

        "UCS-C210" = "2020/Jun"

        "UCS-C220" = "2020/Jun"

        "UCS-C240" = "2018/Aug"

        "UCS-C420" = "2017/Jan"

        "PowerEdge R630" = "2018/May"

        "PowerEdge R710" = "2016/May"

        "PowerEdge R730xd" = "2018/May"

        "PowerEdge R900"  = "2015/Jul"

        "PowerEdge R910" = "2015/Mar"

        }

    # Collect Server details

    $results = @()

    foreach ($vmHost in Get-VMHost) {

        $esxcli = Get-EsxCli -vmhost $vmHost.name -V2 -ErrorAction SilentlyContinue

        $vcName = [System.Net.Dns]::GetHostEntry((get-view $vmHost -ErrorAction SilentlyContinue).summary.managementserverip).HostName

        $vmHostName = $vmHost.Name

        $vmHostVendor = $esxcli.hardware.platform.get.invoke().VendorName

        $vmHostModel = $esxcli.hardware.platform.get.invoke().ProductName

        $vmHostSerial = $esxcli.hardware.platform.get.invoke().SerialNumber

        $EolDate = "Unknown"

        if ($vmHostModelEolMapping.ContainsKey($vmHostModel)){

            $EolDate = $vmHostModelEolMapping[$vmHostModel]

            }

        $prop = [pscustomobject] @{

                vCenter = $vcName

                "ESXi Host Name" = $vmHostName

                Vendor = $vmHostVendor

                Model = $vmHostModel

                Serial = $vmHostSerial

                EOL = $EolDate

        }

        $results+=$prop

    }

    $results | Sort-Object vCenter,"ESXi Host Name" | Export-Csv -path c:\Temp\EOLreport.csv



  • 2.  RE: ESXi Host EOL report
    Best Answer

    Posted Jan 29, 2020 11:53 AM

    When the Get-EsxCli for one or another reason fails, the script will continue with the values of the previous iteration in the loop.

    Perhaps this try-catch construct could avoid that

    $cred = Get-Credential 'username@company.com'

    $vCenters = @(

        "vc1.company.com"

        "vc2.company.com"

        "vc3.company.com"

        "vc4.company.com"

    )

    Connect-VIServer -Server $vCenters -Credential $cred -ErrorAction SilentlyContinue

    # Server model to EOL date mappings, edit to add/correct dates

    $vmHostModelEolMapping = @{

        "UCS-C210"         = "2020/Jun"

        "UCS-C220"         = "2020/Jun"

        "UCS-C240"         = "2018/Aug"

        "UCS-C420"         = "2017/Jan"

        "PowerEdge R630"   = "2018/May"

        "PowerEdge R710"   = "2016/May"

        "PowerEdge R730xd" = "2018/May"

        "PowerEdge R900"   = "2015/Jul"

        "PowerEdge R910"   = "2015/Mar"

    }

    # Collect Server details

    $results = @()

    foreach ($vmHost in Get-VMHost) {

        $vcName = [System.Net.Dns]::GetHostEntry((Get-View $vmHost -ErrorAction SilentlyContinue).summary.managementserverip).HostName

        $vmHostName = $vmHost.Name

        $EolDate = "Unknown"

        $vmHostVendor = ''

        $vmHostModel = ''

        $vmHostSerial = ''


        try {

            $esxcli = Get-EsxCli -vmhost $vmHost -V2 -ErrorAction Stop

            $vmHostVendor = $esxcli.hardware.platform.get.invoke().VendorName

            $vmHostModel = $esxcli.hardware.platform.get.invoke().ProductName

            $vmHostSerial = $esxcli.hardware.platform.get.invoke().SerialNumber

            if ($vmHostModelEolMapping.ContainsKey($vmHostModel)) {

                $EolDate = $vmHostModelEolMapping[$vmHostModel]

            }

        }

        catch {

            Write-Host -ForegroundColor red  "Get-EsxCli failed for $($vmHost.Name)"

        }

        $prop = [pscustomobject] @{

            vCenter          = $vcName

            "ESXi Host Name" = $vmHostName

            Vendor           = $vmHostVendor

            Model            = $vmHostModel

            Serial           = $vmHostSerial

            EOL              = $EolDate

        }

        $results += $prop

    }

    $results | Sort-Object vCenter, "ESXi Host Name" | Export-Csv -path c:\Temp\EOLreport.csv



  • 3.  RE: ESXi Host EOL report

    Posted Jan 29, 2020 06:32 PM

    LucD,

    I ran the script but its shows blanks for all the host with error for each host

      

    ModelSerialEOL
    Unknown
    Unknown
    Unknown
    Unknown
    Unknown
    Unknown
    Unknown
    Unknown
    Unknown
    Unknown
    Unknown
    Unknown
    Unknown


  • 4.  RE: ESXi Host EOL report

    Posted Jan 29, 2020 06:49 PM

    There was a typo in the Get-EsxCli line.
    I corrected the code above, give it another try.



  • 5.  RE: ESXi Host EOL report

    Posted Jan 29, 2020 07:06 PM

    Ok, LucD,

    This time serial/Model is showing but EOL is unknown status...

      

    VendorModelEOL
    Cisco Systems IncUCSB-EX-M4-1Unknown
    Cisco Systems IncUCSB-EX-M4-1Unknown
    Cisco Systems IncUCSB-EX-M4-1Unknown
    Cisco Systems IncUCSB-EX-M4-1Unknown
    Cisco Systems IncUCSB-EX-M4-1Unknown
    Cisco Systems IncUCSB-EX-M4-1Unknown
    Cisco Systems IncUCSB-EX-M4-1Unknown

       

    Cisco Systems IncUCSB-EX-M4-1Unknown
    Cisco Systems IncUCSB-EX-M4-1Unknown
    Cisco Systems IncUCSB-EX-M4-1Unknown
    Cisco Systems IncUCSB-EX-M4-1Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSB-B200-M4Unknown
    Cisco Systems IncUCSC-C220-M4SUnknown
    Cisco Systems IncUCSC-C220-M4SUnknown
    Cisco Systems IncUCSC-C220-M4SUnknown
    Cisco Systems IncUCSC-C220-M4SUnknown

    thanks

    V



  • 6.  RE: ESXi Host EOL report

    Posted Jan 29, 2020 07:14 PM

    The names listed under Model are not present in the $vmHostModelEolMapping hash table.
    So the 'Unknown' seems to be correct



  • 7.  RE: ESXi Host EOL report

    Posted Jan 29, 2020 11:40 PM

    Thanks Luc, that worked as expected.

    After your first suggestion i got a lot of blank information back but quickly spotted the typo and once corrected it worked perfectly, thanks.

    To anyone who wants to use this, run it first to get back the server model details as, this information is detailed on the Host, e.g. you may be using Cisco UCS C210's but, this report identifies these as R210-2121605W .

    When you have all your Server models, google the EOL date and edit the  $vmHostModelEolMapping hash table to match your servers.



  • 8.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 11:56 AM

    I've re-worked this to make it a bit more user friendly :smileygrin:

    The script can take a long time to run, depending on quantity of VC's and Hosts so i've also added a progress bar.

    If anyone thinks this can be optimized in any way, please feel free to post comments

    # login to vCenter(s) - use CTRL to select multiple vCenters

    $cred = Get-Credential -Message "  ***********  Enter vCenter Credentials  ***********"

    $vCenters = @(

        "vc1.company.com"

        "vc2.company.com"

        "vc3.company.com"

        "vc4.company.com"

        "vc5.company.com"

        )

    $selectedVC = $vCenters | Out-GridView -Title "  ***  vCenter Listing - Select required vCenter(s)  ***" -OutputMode Multiple

    Connect-VIServer -Server $selectedVC -Credential $cred -ErrorAction SilentlyContinue

    # Server model to EOL date mappings, edit to add/correct dates

    $vmHostModelEolMapping = @{

        # Cisco Servers

        "B230-BASE-M2" = "2020/Jun"

        "C260-BASE-2646" = "2020/Jun"

        "UCSB-B200-M4" = "2024/Feb"

        "UCSC-BASE-M2-C460" = "2020/Apr"

        # Dell Servers

        "PowerEdge R630" = "2018/May"

        "PowerEdge R640" = " "

        "PowerEdge R710" = "2016/May"

        # VxRails

        "VxRail E460" = "2023/05"

        "VxRail P570F"= " "

        }

    # Status Bar Variables

    $vmHosts = Get-VMHost

    $count = $vmHosts.count

    $i = 1

    # Collect Server details

    $results = @()

    foreach ($vmHost in $vmHosts) {

        Write-Progress -Activity "Generating Server End Of Life Report" -Status "Getting info on $vmHost" -PercentComplete (($i*100)/$count)

        $vcName = [System.Net.Dns]::GetHostEntry((Get-View $vmHost -ErrorAction SilentlyContinue).summary.managementserverip).HostName

        $vmHostName = $vmHost.Name

        $EolDate = "Unknown"

        $vmHostVendor = ''

        $vmHostModel = ''

        $vmHostSerial = ''

        try {

            $esxcli = $null

            $esxcli = Get-EsxCli -vmhost $vmHost -V2 -ErrorAction Stop

            $vmHostVendor = $esxcli.hardware.platform.get.invoke().VendorName

            $vmHostModel = $esxcli.hardware.platform.get.invoke().ProductName

            $vmHostSerial = $esxcli.hardware.platform.get.invoke().SerialNumber

            if ($vmHostModelEolMapping.ContainsKey($vmHostModel)) {

                $EolDate = $vmHostModelEolMapping[$vmHostModel]

                }

            }

        catch {

            Write-Host -ForegroundColor red  "Get-EsxCli failed for $($vmHost.Name)"

            }

        $prop = [pscustomobject] @{

            vCenter          = $vcName

            "ESXi Host Name" = $vmHostName

            Vendor           = $vmHostVendor

            Model            = $vmHostModel

            Serial           = $vmHostSerial

            EOL              = $EolDate

            }

       

        $i++

        $results += $prop

    }

    <#

        requirement: ImportExcel module

        Verify that ImportExcel is installed with 'Get-Module -ListAvailable ImportExcel'

        If not installed, install with 'Find-Module ImportExcel | Install-Module'

        Get available commands with 'Get-Command -Module ImportExcel'

    #>

    If (!(Get-module -ListAvailable "ImportExcel")) {

        Find-Module -Name ImportExcel | Install-Module

        }

    $ContainsBlanks = New-ConditionalText -ConditionalType ContainsBlanks

    $hash = @{

        Path = "C:\Temp\EOLreport.xlsx"

        Show = $true;

        AutoSize = $true;

        AutoFilter = $true;

        ConditionalText = $ContainsBlanks

        ShowPercent = $true;

        #PivotTableName = "ESXi Version Detail";

        #IncludePivotTable = $true;

        #PivotRows = 'Version';

        #PivotData = @{'Version' = 'Count'};

        #IncludePivotChart = $true;

        #ChartType = "PieExploded";

        HideSheet = "Sheet1";

        }

    Remove-Item $hash.Path -ErrorAction Ignore

    $results | Sort-Object vCenter,"ESXi Host Name" | Export-Excel @hash



  • 9.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 12:33 PM

    Great, thanks for sharing that.

    While playing with the script, I think there might be some performance improvements possible.

    By using Foreach-Object and a Pipelinevariable, everything can be set up in a pipeline construct.
    No need to have a $results variable.

    The following also only uses 1 $esxcli method call, instead of three.

    The If-Then for the EOL can also be eliminated.

    If the Model is not in the hash table, it will return $null. Since the -replace operator can use a RegEx, we test for an empty string () with "^$") and replace it with 'Unknown'.


    These are not corrections, just some suggestions :smileygrin:


    # login to vCenter(s) - use CTRL to select multiple vCenters

    $cred = Get-Credential -Message "  ***********  Enter vCenter Credentials  ***********"

    $vCenters = @(

        "vc1.company.com"

        "vc2.company.com"

        "vc3.company.com"

        "vc4.company.com"

        "vc5.company.com"

    )

    $selectedVC = $vCenters | Out-GridView -Title "  ***  vCenter Listing - Select required vCenter(s)  ***" -OutputMode Multiple

    Connect-VIServer -Server $selectedVC -Credential $cred -ErrorAction SilentlyContinue

    # Server model to EOL date mappings, edit to add/correct dates

    $vmHostModelEolMapping = @{

        # Cisco Servers

        "B230-BASE-M2"      = "2020/Jun"

        "C260-BASE-2646"    = "2020/Jun"

        "UCSB-B200-M4"      = "2024/Feb"

        "UCSC-BASE-M2-C460" = "2020/Apr"

        # Dell Servers

        "PowerEdge R630"    = "2018/May"

        "PowerEdge R640"    = " "

        "PowerEdge R710"    = "2016/May"

        # VxRails

        "VxRail E460"       = "2023/05"

        "VxRail P570F"      = " "

    }

    If (!(Get-Module -ListAvailable "ImportExcel")) {

        Find-Module -Name ImportExcel | Install-Module

    }


    $ContainsBlanks = New-ConditionalText -ConditionalType ContainsBlanks

    $hash = @{

        Path            = "C:\Temp\EOLreport.xlsx"

        Show            = $true;

        AutoSize        = $true;

        AutoFilter      = $true;

        ConditionalText = $ContainsBlanks

        ShowPercent     = $true;

        #PivotTableName = "ESXi Version Detail";

        #IncludePivotTable = $true;

        #PivotRows = 'Version';

        #PivotData = @{'Version' = 'Count'};

        #IncludePivotChart = $true;

        #ChartType = "PieExploded";

        HideSheet       = "Sheet1";

    }

    Remove-Item $hash.Path -ErrorAction Ignore


    Get-VMHost -PipelineVariable vmhost |

    ForEach-Object -Process {

        try {

            $esxcli = Get-EsxCli -vmhost $vmHost -V2 -ErrorAction Stop

            $platform = $esxcli.hardware.platform.get.invoke()

        }

        catch {

            Write-Host -ForegroundColor red  "Get-EsxCli failed for $($vmHost.Name)"

        }

        [pscustomobject] @{

            vCenter          = [System.Net.Dns]::GetHostEntry((Get-View $vmHost -ErrorAction SilentlyContinue).summary.managementserverip).HostName

            "ESXi Host Name" = $vmHost.Name

            Vendor           = $platform.VendorName

            Model            = $platform.ProductName

            Serial           = $platform.SerialNumber

            EOL              = $vmHostModelEolMapping[$platform.ProductName] -replace "^$", 'Unknown'

        }

    } | Sort-Object vCenter, "ESXi Host Name" | Export-Excel @hash



  • 10.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 01:14 PM

    LucD,

    I tried to excute but it shows an error and it never proceed further in console.

    Name                           Port  User

    ----                           ----  ----

    vc1.sg.con... 443   SGC\vk1

    Install-Module : Administrator rights are required to install modules in 'C:\Program Files\WindowsPowerShell\Modules'.

    Log on to the computer with an account that has Administrator rights, and then try again, or install

    'D:\Users\vk1\Documents\WindowsPowerShell\Modules' by adding "-Scope CurrentUser" to your command. You can

    also try running the Windows PowerShell session with elevated rights (Run as Administrator).

    At D:\vk1\ESXHost-EOL.ps1:63 char:37

    +     Find-Module -Name ImportExcel | Install-Module

    +                                     ~~~~~~~~~~~~~~

        + CategoryInfo          : InvalidArgument: (:) [Install-Module], ArgumentException

        + FullyQualifiedErrorId : InstallModuleNeedsCurrentUserScopeParameterForNonAdminUser,Install-Module

    New-ConditionalText : The term 'New-ConditionalText' is not recognized as the name of a cmdlet, function, script file,

    or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and

    try again.

    At D:\vk1\ESXHost-EOL.ps1:68 char:19

    + $ContainsBlanks = New-ConditionalText -ConditionalType ContainsBlanks

    +                   ~~~~~~~~~~~~~~~~~~~

        + CategoryInfo          : ObjectNotFound: (New-ConditionalText:String) [], CommandNotFoundException

        + FullyQualifiedErrorId : CommandNotFoundException

    Get-EsxCli failed for ESX2.host.com

    thanks

    V



  • 11.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 01:24 PM

    To install a module for All Users, you have to start your PowerShell sessions 'As Administrator'.
    The alternative is to install the module for the CurrentUser (the -Scope CurrentUser mentioned in the error).



  • 12.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 01:35 PM

    Ok, i did run as Administrator but it ended with blank report. EOLreport.csv = 0 KB

    thanks

    V



  • 13.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 01:42 PM

    My bad, I didn't place the object in the pipeline.
    I corrected the code above



  • 14.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 02:17 PM

    Ok, i did run the script,

    Get-VMHost : 1/30/2020 7:43:34 PM       Get-VMHost              Sequence contains more than one matching eleme

    t D:\vmk\ESXHost-EOL.ps1:110 char:1

    Get-VMHost -PipelineVariable vmhost |

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

       + CategoryInfo          : NotSpecified: (:) [Get-VMHost], VimException

       + FullyQualifiedErrorId : Core_BaseCmdlet_UnknownError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetVMH

    xception calling "GetHostEntry" with "1" argument(s): "No such host is known"

    t D:\vmk\ESXHost-EOL.ps1:130 char:5

         [pscustomobject] @{

         ~~~~~~~~~~~~~~~~~~~

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : SocketException

    xception calling "GetHostEntry" with "1" argument(s): "No such host is known"

    t D:\vmk\ESXHost-EOL.ps1:130 char:5

         [pscustomobject] @{

         ~~~~~~~~~~~~~~~~~~~

       + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException

       + FullyQualifiedErrorId : SocketException

    xception calling "GetHostEntry" with "1" argument(s): "No such host is known"

    t D:\vmk\ESXHost-EOL.ps1:130 char:5

    Get-EsxCli failed for Host2.com

    thanks

    V



  • 15.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 02:29 PM

    Not sure what is happening there, must be something in your script.

    Also confused by the line numbers in the errors.

    Line 110?

    What else is in that .ps1 file?



  • 16.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 06:03 PM

    Thanks Luc,

    Those optimizations are great, really helpful.

    One question with them though. Previously i was using a count of the Hosts to generate a status bar

    # Status Bar Variables

    $vmHosts = Get-VMHost

    $count = $vmHosts.count

    $i = 1

    # Collect Server details

    $results = @()

    foreach ($vmHost in $vmHosts) {

        Write-Progress -Activity "Generating Server End Of Life Report" -Status "Getting info on $vmHost" -PercentComplete (($i*100)/$count)

    Using a pipeline variable, how do i now count the total Hosts ?

    Should i do something like

    $vmHosts = Get-VMHost

    $count = $vmHosts.count

    $i = 1

    Get-VMHost -PipelineVariable $vmhosts |

    ForEach-Object -Process {



  • 17.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 06:16 PM

    I would avoid doing the Get-VMHost twice.

    As a skeleton, something like this

    $vmHostAll = Get-VMHost

    $i = 1

    $vmHostAll | ForEach-Object -PipelineVariable vmhost -Process {

        Write-Progress -PercentComplete ($i/$vmhostAll.Count*100) -Activity 'In loop'

        $i++

    }



  • 18.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 07:12 PM

    Getting an error (and looks like i don't fully understand your optimizations)

    $vmHostAll = Get-VMHost


    = 1


    | ForEach-Object -PipelineVariable vmhost -Process {

    Write-Progress -PercentComplete ($i/$vmHostAll.count*100) -Activity "Generating Server End Of Life Report" -Status "Getting info on $vmHost"


    $i++


    try {

    $esxcli = Get-EsxCli -vmhost $vmHost -V2 -ErrorAction Stop


    $platform = $esxcli.hardware.platform.get.invoke()

    catch {

    Write-Host -ForegroundColor red  "Get-EsxCli failed for $($vmHost.Name)"


    the above returns

    Get-EsxCli failed for

    Get-View : Cannot validate argument on parameter 'VIObject'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.

    At line:135 char:69

    + ... r          = [System.Net.Dns]::GetHostEntry((Get-View $vmHost -ErrorA ...

    +                                                           ~~~~~~~

        + CategoryInfo          : InvalidData: (:) [Get-View], ParameterBindingValidationException

        + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView



  • 19.  RE: ESXi Host EOL report

    Posted Jan 30, 2020 07:23 PM

    Not sure where that Get-View is coming from.

    In any case, this is the complete script with the Write-Progress.

    # login to vCenter(s) - use CTRL to select multiple vCenters

    $cred = Get-Credential -Message "  ***********  Enter vCenter Credentials  ***********"

    $vCenters = @(

        "vc1.company.com"

        "vc2.company.com"

        "vc3.company.com"

        "vc4.company.com"

        "vc5.company.com"

    )

    $selectedVC = $vCenters | Out-GridView -Title "  ***  vCenter Listing - Select required vCenter(s)  ***" -OutputMode Multiple

    Connect-VIServer -Server $selectedVC -Credential $cred -ErrorAction SilentlyContinue

    # Server model to EOL date mappings, edit to add/correct dates

    $vmHostModelEolMapping = @{

        # Cisco Servers

        "B230-BASE-M2"      = "2020/Jun"

        "C260-BASE-2646"    = "2020/Jun"

        "UCSB-B200-M4"      = "2024/Feb"

        "UCSC-BASE-M2-C460" = "2020/Apr"

        # Dell Servers

        "PowerEdge R630"    = "2018/May"

        "PowerEdge R640"    = " "

        "PowerEdge R710"    = "2016/May"

        # VxRails

        "VxRail E460"       = "2023/05"

        "VxRail P570F"      = " "

    }

    If (!(Get-Module -ListAvailable "ImportExcel")) {

        Find-Module -Name ImportExcel | Install-Module

    }


    ContainsBlanks = New-ConditionalText -ConditionalType ContainsBlanks

    $hash = @{

        Path            = "C:\Temp\EOLreport.xlsx"

        Show            = $true;

        AutoSize        = $true;

        AutoFilter      = $true;

        ConditionalText = $ContainsBlanks

        ShowPercent     = $true;

        #PivotTableName = "ESXi Version Detail";

        #IncludePivotTable = $true;

        #PivotRows = 'Version';

        #PivotData = @{'Version' = 'Count'};

        #IncludePivotChart = $true;

        #ChartType = "PieExploded";

        HideSheet       = "Sheet1";

    }

    Remove-Item $hash.Path -ErrorAction Ignore


    $vmHostAll = Get-VMHost


    $i = 1

    $vmHostAll | ForEach-Object -PipelineVariable vmhost -Process {

        Write-Progress -PercentComplete ($i / $vmHostAll.count * 100) -Activity "Generating Server End Of Life Report" -Status "Getting info on $vmHost"

        $i++


        try {

            $esxcli = Get-EsxCli -vmhost $vmHost -V2 -ErrorAction Stop

            $platform = $esxcli.hardware.platform.get.invoke()

        }

        catch {

            Write-Host -ForegroundColor red  "Get-EsxCli failed for $($vmHost.Name)"

        }

        [pscustomobject] @{

            vCenter          = [System.Net.Dns]::GetHostEntry((Get-View $vmHost -ErrorAction SilentlyContinue).summary.managementserverip).HostName

            "ESXi Host Name" = $vmHost.Name

            Vendor           = $platform.VendorName

            Model            = $platform.ProductName

            Serial           = $platform.SerialNumber

            EOL              = $vmHostModelEolMapping[$platform.ProductName] -replace "^$", 'Unknown'

        }

    } | Sort-Object vCenter, "ESXi Host Name" | Export-Excel @hash



  • 20.  RE: ESXi Host EOL report

    Posted Jan 31, 2020 11:06 AM

    Thanks Luc,

    Running your last iteration of the code, i was still getting errors. Through a process of trial and error i spotted that the when using $vmhost variable,the following calls were failing

    • Get-EsxCli was returning nothing
    • Get-View was complaining about a null or empty argument

    Get-EsxCli failed for

    Get-View : Cannot validate argument on parameter 'VIObject'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.

    At line:138 char:69

    + ... r          = [System.Net.Dns]::GetHostEntry((Get-View $vmHost -ErrorA ...

    +                                                           ~~~~~~~

        + CategoryInfo          : InvalidData: (:) [Get-View], ParameterBindingValidationException

        + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView

    I changed the code to the below (replacing the $vmhost with $_ in the "try" statement and in the [pscustomobject])

    $vmHostAll = Get-VMHost

    $i = 1

    $vmHostAll | ForEach-Object -PipelineVariable vmhost -Process {

        Write-Progress -PercentComplete ($i / $vmHostAll.count * 100) -Activity "Generating Server End Of Life Report" -Status "Getting info on $vmHost"

        read-host "Press ENTER to Continue..."

        $i++

        try {

            $esxcli = Get-EsxCli -vmhost $_ -V2 -ErrorAction Stop

            $platform = $esxcli.hardware.platform.get.invoke()

            }

        catch {

            Write-Host -ForegroundColor red  "Get-EsxCli failed for $($_.Name)"

            }

        [pscustomobject] @{

            vCenter          = [System.Net.Dns]::GetHostEntry((Get-View $_ -ErrorAction SilentlyContinue).summary.managementserverip).HostName

            "ESXi Host Name" = $_.Name

            Vendor           = $platform.VendorName

            Model            = $platform.ProductName

            Serial           = $platform.SerialNumber

            EOL              = $vmHostModelEolMapping[$platform.ProductName] -replace "^$", 'Unknown'

            }

    } | Sort-Object vCenter, "ESXi Host Name" | Export-Excel @hash

    The output was now correct except for the Progress Bar, the Status was now reading

    "Getting info on @{vCenter=vc1.company.com; ESXi Host Name=Host1.company.com; Vendor=Dell; Model=Poweredge R910; Serial =123abc; EOL=2015/Mar/29}"

    I switched the Status from "Getting info on $vmHost" to "Getting info on $_", ran the code again and it worked 100%

    I haven't used pscustomobjects before so don't understand what's happening here but, wanted to post it in case it helps others.

    To keep this comment clean, i'm attaching the working code with your optimizations

    Thanks again !



  • 21.  RE: ESXi Host EOL report

    Posted Jan 31, 2020 11:42 AM

    My bad, the PipelineVariable on a Foreach-Object doesn't work that way.

    Try with this version

    # login to vCenter(s) - use CTRL to select multiple vCenters

    $cred = Get-Credential -Message "  ***********  Enter vCenter Credentials  ***********"


    $vCenters = @(

        "vc1.company.com"

        "vc2.company.com"

        "vc3.company.com"

        "vc4.company.com"

        "vc5.company.com"

        )


    $selectedVC = $vCenters | Out-GridView -Title "  ***  vCenter Listing - Select required vCenter(s)  ***" -OutputMode Multiple

    Connect-VIServer -Server $selectedVC -Credential $cred -ErrorAction SilentlyContinue

    # Server model to EOL date mappings, edit to add/correct dates

    $vmHostModelEolMapping = @{

        # Cisco Servers

        "B230-BASE-M2"      = "2020/Jun"

        "C260-BASE-2646"    = "2020/Jun"

        "UCSB-B200-M4"      = "2024/Feb"

        "UCSC-BASE-M2-C460" = "2020/Apr"

        # Dell Servers

        "PowerEdge R630"    = "2018/May"

        "PowerEdge R640"    = "No EOL Published"

        "PowerEdge R710"    = "2016/May"

        # VxRails

        "VxRail E460"       = "2023/05"

        "VxRail P570F"      = "No EOL Published"

        }


    # Install the ImportExcel module if not already installed and prepare Excel layout

    If (!(Get-module -ListAvailable "ImportExcel")) {

        Find-Module -Name ImportExcel | Install-Module -Scope CurrentUser

        }


    $ContainsBlanks = New-ConditionalText -ConditionalType ContainsBlanks


    $hash = @{

        Path = "C:\Temp\EOLreport.xlsx"

        Show = $true;

        AutoSize = $true;

        AutoFilter = $true;

        ConditionalText = $ContainsBlanks

        ShowPercent = $true;

        #HideSheet = "Sheet1";

        }


    Remove-Item $hash.Path -ErrorAction Ignore


    # Collect ESXi Host details for EOL Report

    $vmHostAll = Get-VMHost

    $i = 1


    $vmHostAll | ForEach-Object -Process {

        $vmHost = $_

        Write-Progress -PercentComplete ($i / $vmHostAll.count * 100) -Activity "Generating Server End Of Life Report" -Status "Getting info on ($vmHost.Name))"

        $i++


        try {

            $esxcli = Get-EsxCli -vmhost $vmHost -V2 -ErrorAction Stop

            $platform = $esxcli.hardware.platform.get.invoke()

            }


        catch {

            Write-Host -ForegroundColor red  "Get-EsxCli failed for $($vmHost.Name)"

            }

        [pscustomobject] @{

            vCenter          = [System.Net.Dns]::GetHostEntry((Get-View $vmHost -ErrorAction SilentlyContinue).summary.managementserverip).HostName

            "ESXi Host Name" = $vmHost.Name

            Vendor           = $platform.VendorName

            Model            = $platform.ProductName

            Serial           = $platform.SerialNumber

            EOL              = $vmHostModelEolMapping[$platform.ProductName] -replace "^$", 'Unknown'

            }


    } | Sort-Object vCenter, "ESXi Host Name" | Export-Excel @hash