Невозможно вернуть информацию о хостах в нескольких кластерах в PowerShell с помощью PowerCLI

У меня есть сценарий PowerShell, который используется для возврата информации для каждого хоста в указанном пользователем кластере. Пользователь указывает vCenter и кластер в качестве параметров, и сценарий работает должным образом.

Я пытаюсь изменить этот сценарий, чтобы пользователю нужно было только передать vCenter в качестве параметра, и он возвращал информацию для всех хостов во всех кластерах.

Вот оригинальный скрипт, который у меня есть, который работает:

Param(
    $vc,
    $ClusterName
)

Add-PSSnapin VMware.VimAutomation.Core

Connect-VIServer $vc

$VMHosts = Get-Cluster $ClusterName | Get-VMHost  | ? { $_.ConnectionState -eq "Connected" } | Sort-Object -Property Name

foreach ($VMHost in $VMHosts) {

 Get-VMHostStorage -RescanAllHba -VMHost $VMHost | Out-Null
 $esx = Get-VMHost $VMHost
 foreach($hba in (Get-VMHostHba -VMHost $esx -Type "FibreChannel")){
     $target = ((Get-View $hba.VMhost).Config.StorageDevice.ScsiTopology.Adapter | where {$_.Adapter -eq $hba.Key}).Target
     $luns = Get-ScsiLun -Hba $hba  -LunType "disk"
     $nrPaths = ($target | %{$_.Lun.Count} | Measure-Object -Sum).Sum
     $deadPaths = $luns | Get-ScsiLunPath | Group-Object -Property state | ? { $_.Name -eq "Dead"}
     $hbaDevice = $hba.Device
     $targetCount = $target.Count
     $lunsCount = $luns.Count
     $deadPathCount = $deadPaths.Count

     "vmhost=$VMHost;hba=$hbaDevice;targets=$targetCount;devices=$lunsCount;paths=$nrPaths;deadpaths=$deadPathsCount|"

 }
}

Disconnect-VIServer -Confirm:$False

А вот моя модифицированная версия:

Param(
    $vc
)

Add-PSSnapin VMware.VimAutomation.Core

Connect-VIServer $vc
$clusters = Get-Cluster

foreach ($cluster in $clusters) {

    $clusterName = $cluster.name
    $VMHosts = Get-Cluster $clusterName | Get-VMHost  | ? { $_.ConnectionState -eq "Connected" } | Sort-Object -Property Name


    foreach ($VMHost in $VMHosts) {


        Get-VMHostStorage -RescanAllHba -VMHost $VMHost | Out-Null
        $esx = Get-VMHost $VMHost

        foreach($hba in (Get-VMHostHba -VMHost $esx -Type "FibreChannel")){
            $target = ((Get-View $hba.VMhost).Config.StorageDevice.ScsiTopology.Adapter | where {$_.Adapter -eq $hba.Key}).Target
            $luns = Get-ScsiLun -Hba $hba  -LunType "disk"
            $nrPaths = ($target | %{$_.Lun.Count} | Measure-Object -Sum).Sum
            $deadPaths = $luns | Get-ScsiLunPath | Group-Object -Property state | ? { $_.Name -eq "Dead"}
            $hbaDevice = $hba.Device
            $targetCount = $target.Count
            $lunsCount = $luns.Count
            $deadPathCount = $deadPaths.Count
            "vmhost=$VMHost;hba=$hbaDevice;targets=$targetCount;devices=$lunsCount;paths=$nrPaths;deadpaths=$deadPathsCount|"
        }
    }
}



Disconnect-VIServer -Confirm:$False

Ошибка, которую я получаю:

Could not execute powershell command.
At \\xx\xxx\xxxx\scripts\vmwarePathCheckAllClusters.ps1:35 char:26
+         Get-VMHostStorage <<<<  -RescanAllHba -VMHost $VMHost | Out-Null

Кажется, что $VMHost возвращается как null, но я не могу понять, почему!

Я впервые использую PowerCLI CommandLets, и я также новичок в PowerShell. Я уверен, что это что-то очень простое, и буду признателен за любую помощь. Если вам потребуется дополнительная информация, я буду более чем счастлив предоставить. УДАР!

РЕДАКТИРОВАТЬ: Вот дополнительная информация об ошибке:

+         Get-VMHostStorage <<<<  -RescanAllHba -VMHost $VMHost | Out-Null ---> VMware.VimAutomation.Sdk.Types.V1.ErrorHandling.VimException.VimException: 9/24/2014 5:58:57 AM Get-VMHostStorage       Value cannot be found for the mandatory parameter VMHost     ---> System.Management.Automation.ParameterBindingException: Value cannot be found for the mandatory parameter VMHost

person Zanmato    schedule 22.09.2014    source источник
comment
Вы пытались запустить консоль Powershell с повышенными привилегиями? Без этого может быть невозможно правильно получить $VMHosts.   -  person Kris Powell    schedule 22.09.2014
comment
Да, я изначально не был, и он вернул ошибку, в которой говорилось, что мне нужны повышенные привилегии. Спасибо.   -  person Zanmato    schedule 22.09.2014
comment
Любые другие идеи относительно того, почему это не сработает? Мне кажется странным, что оригинальный скрипт работает нормально. Я проводил некоторые тесты, и $VMHost возвращает правильные хосты для кластера!   -  person Zanmato    schedule 23.09.2014
comment
Хм... К сожалению, я не работал с кластерами в явном виде (или тестировал), так что прямых идей у ​​меня нет. Можете ли вы успешно заставить все свои кластеры заполнить вашу переменную $clusters? Если да, то когда вы используете свой первый цикл foreach, правильно ли $cluster.name заполняет $ClusterName? Кроме того, возможно, изменение вашего кода для использования одного кластера в качестве теста может пролить некоторый свет на то, существует ли другая основная проблема, отличная от вашего измененного сценария.   -  person Kris Powell    schedule 23.09.2014
comment
Привет, Крис, спасибо, что вернулся ко мне. Да, переменные $cluster и $clusterName заполняются правильно. Я попробовал ваше предложение, изменив код, чтобы принять только один статически установленный кластер. Поменял $clusters = Get-Cluster на $clusters = @("server_name") и все заработало! К сожалению, я до сих пор не могу понять, почему это происходит. Спасибо за предложение.   -  person Zanmato    schedule 24.09.2014


Ответы (1)


Вы тестировали запуск Get-VMHostStorage без -RescanAllHBA? Как вы думаете, почему $VMHost возвращается как null? Может хост находит, а пересканировать нечего? Просто предположение.

Не уверен, что это может вызвать вашу проблему, но вам не нужно запускать Get-Cluster дважды. Скорее,

$VMHosts = $cluster | Get-VMHost  | ? <etc>

редактировать — сколько раз для данного запуска скрипта появляется полный текст ошибки? Сколько vmhosts было найдено в этом прогоне? У вас есть кластер без хостов? Хост без хранилища? Вы можете установить $vmhost = $null или $cluster = $null, если значение из одной итерации цикла искажает следующую итерацию. (Извините, должен быть лучший способ сформулировать это... надеюсь, вы уловили мою мысль.) Вы всегда можете поместить оскорбительную строку кода в блок [try] и обработать ошибку с помощью поймать.

редактировать еще раз - по-видимому, это исправлено для хост в режиме обслуживания: if (!$VMHost) {continue}

person noam    schedule 23.09.2014
comment
Привет, @noam, спасибо за ответ. Я попробовал оба ваших предложения выше, и, к сожалению, я все еще получаю ту же ошибку. Причина, по которой я думаю, что это как-то связано с $VMHost, связана с дополнительной частью возвращаемой ошибки, которую я забыл опубликовать выше. Я добавлю это в исходный вопрос сейчас. - person Zanmato; 24.09.2014
comment
Спасибо, @noam, это было так. Теперь он работает, как и ожидалось. В одном из кластеров была одна виртуальная машина в режиме обслуживания. Если ты когда-нибудь будешь в Белфасте, я должен тебе пинту :) - person Zanmato; 24.09.2014
comment
Только что видел, как ты обновился. Я действительно использовал ваш оригинальный ответ, чтобы добавить if(!$VMHost){continue}, который отлично работает для меня. - person Zanmato; 24.09.2014
comment
упс - я снова отредактирую ответ, чтобы включить это. Спасибо за уточнение. - person noam; 24.09.2014