Недоступная хэш-таблица Powershell в функции

#function #powershell #variables #hashtable

#функция #powershell #переменные #хэш-таблица

Вопрос:

Я создал функцию для импорта записей HR, чтобы они были легко доступны путем индексации идентификатора сотрудника.

 function hrDataImport {
$HRFile=Import-Csv $rawHRFile #$rawHRFile path previously defined
Write-Host "Creating HR hash table..."
$hrData = @{}
$HRFile | ForEach-Object { $hrData[$_.employeeID] = $_ }
Write-Host "Done. " $hrData.Count
    }
 

Я бы хотел использовать эту переменную $hrData вне функции. Я не могу ссылаться на $hrData[‘EmployeeID’], поскольку я читал, что переменные в функциях не существуют вне функции. Одна вещь, которую я пробовал, — это создание другой функции для передачи идентификатора сотрудника в хэш-таблицу $ hrData:

 function showHRData {
    param ([string]$hrUser)
    $hrData[$hrUser]
}
 

Я поместил функции в модуль и успешно импортировал. Я могу нормально выполнить importHRData, но когда я пытаюсь showHRData -hrUser $employeeID , я получаю «Невозможно индексировать в нулевой массив». Похоже, что функция не видит переменную хэш-таблицы из предыдущей функции. Что я делаю не так или что бы вы предложили, чтобы я мог получить доступ к этой хэш-таблице $ hrData в разных сценариях?

Комментарии:

1. вы можете либо определить хэш-таблицу вне функции, чтобы при обращении к ней в функции она была видна по ссылке. вы также можете попробовать что-то вроде New-Variable -Name TestHashtable -Value @{} -Scope Script создания $Var в вашей функции и сделать так, чтобы он отображался везде в вашем скрипте.

2. И вы, конечно, также можете вернуть его: return $hrData . А затем вызовите свою функцию следующим образом: $myHrData = hrDataImport

Ответ №1:

Вы можете создать хеш-таблицу в своей функции, используя $global (или $script ) область, подобную этой:

 function hrDataImport {
    $HRFile = Import-Csv $rawHRFile #$rawHRFile path previously defined
    Write-Host "Creating HR hash table..."
    if (!$hrData) { $Global:hrData = @{} }
    $HRFile | ForEach-Object { $Global:hrData[$_.employeeID] = $_ }
    Write-Host "Done. " $hrData.Count
}
 

Но в целом рекомендуется избегать глобальной (или скриптовой) области, главным образом потому, что она может конфликтовать с переменными в текущей области.
Чтобы свести к минимуму эту возможность, я бы подумал о том, чтобы изменить ответственность вашей функции не только на загрузку информации, но и на получение соответствующей employeeID , например:

 function Get-EmployeeData ($EmployeeID) {
    if (!$StaticEmployeeData) {
        Write-Host "Creating HR hash table..."
        $HRFile = Import-Csv $rawHRFile #$rawHRFile path previously defined
        $Global:StaticEmployeeData = @{}
        $HRFile | ForEach-Object { $Global:StaticEmployeeData[$_.employeeID] = $_ }
        Write-Host "Done. " $StaticEmployeeData.Count
    }
    $Global:StaticEmployeeData[$employeeID]
}

function showHRData {
    param ([string]$hrUser)
    Get-EmployeeData $hrUser
}
 

В этом случае вы можете выбрать более конкретное имя глобальной переменной (например $StaticEmployeeData , зная, что PowerShell не поддерживает что-то вроде статической переменной), и в качестве дополнительного бонуса данные загружаются только в первый раз, когда они вам действительно нужны (отложенная оценка).

Комментарии:

1. Я добавил «return $hrData» в функцию hrDataImport, и в моем скрипте я установил переменную, равную hrDataImport. Спасибо за совет.