Использование Test-Path для поиска значения в хеш-таблице - PullRequest
0 голосов
/ 27 апреля 2018

Я недавно начал использовать Set-StrictMode, чтобы лучше разбираться в сценариях (т. Е. Объявлять переменные и тому подобное), и столкнулся с небольшой проблемой. Для большинства моих сценариев я создам хеш-таблицу $Script = @{}, а затем объявляю все переменные, используемые в сценарии, как подчиненные свойства в соответствии с этим, потому что независимо от того, что при запуске сценария все переменные будут чистыми, и если вы распечатаете все переменные в конце вашего скрипта, вы знаете, они будут из этого конкретного сеанса.

Исторически, если бы мне нужно было увидеть, была ли объявлена ​​подвариабельная переменная, такая как $Script.RunOnce, я бы просто использовал If ($Script.RunOnce) {}, но в строгом режиме вы должны сделать что-то вроде этого If (Test-Path Variable:\Script.WriteOnce) {}, за исключением того, что test-path видит "Скрипт" .WriteOnce "как собственная переменная, а не под-переменные под $Script

Зачем мне это делать, спросите вы? Что ж, я пишу функцию, которая использует .Net Streamwriter, и я хочу убедиться, что если переменная "$ WriteTee.StreamWriter" существует, запустите $WriteTee.StreamWriter.Close и $WriteTee.StreamWriter.Flush до объявления $Write-Tee снова или когда я пытаюсь при открытии нового потокового редактора произойдет ошибка, и мне придется вручную закрыть дескриптор .net для файла, прежде чем я смогу продолжить тестирование сценария.

Короче говоря
Есть ли способ проверить $WriteTee.StreamWriter с помощью Test-Path или каким-либо другим способом, который не создает ошибку с Set-Strictmode

Супер распотрошенный пример версии моего сценария.

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Inquire'

Function Write-Tee {
    Begin {
        #Variables that are needed only the first time the log function is started.
        If ($WriteTee.RunOnce) {
            If ($WriteTee.StreamWriter) { Write-Tee -Severity Error -Message "Log Writer Already Open. Attempting to close." -Close}
            New-Variable -ErrorAction SilentlyContinue -Force -Name WriteTee -Value @{} -Scope Script
            $Script:WriteTee.RunOnce = $True
        }
    }#End-Begin

    Process {}#End-Process
    End {
        If ($Close -AND $Script:WriteTee) {
            Write-Tee -Severity Info -Message "Flushing Log Writer and closing."
            $WriteTee.StreamWriter.Flush()
            $WriteTee.StreamWriter.Close()
            Remove-Variable -ErrorAction SilentlyContinue -Force -Name WriteTee -Scope Script
            Remove-Variable -ErrorAction SilentlyContinue -Force -Name WriteTee
        }#End-If
    }#End-End
}

Write-Tee -Message "Test" -Severity "Warning"

1 Ответ

0 голосов
/ 27 апреля 2018

Вы можете использовать test-path с поставщиком переменной и именем переменной, чтобы узнать, была ли назначена переменная, но при поиске свойств переменной (или элементов в хеш-таблице, не ясно, с кем вы имеете дело с) требуется другая тактика: Чтобы узнать, есть ли в хеш-таблице элемент с ключом, вы можете сделать что-то вроде:

$writeTee.ContainsKey('StreamWriter')   #returns $true or $false

Чтобы узнать, имеет ли переменная определенное свойство, вы можете использовать get-member:

$writeTee | Get-Member -name StreamWriter   #returns the member or nothing
...