Powershell - "Clear-Item variable:" vs " Remove-Variable"
При временном хранении текста в переменных powershell во время выполнения каков наиболее эффективный способ удаления содержимого переменных из памяти, когда оно больше не требуется?
Я использовал и Clear-Item variable:, и Remove-Variable, но как быстро что-то удаляется из памяти с последним против обнуления содержимого памяти с первым?
EDIT: мне следовало бы немного прояснить, почему я спрашиваю.
Я автоматизирую вход RDP для группы виртуальных машин приложений (приложение не делает запуск как сервис, аутсорсинг разработчиков, долгая история).
Итак, я разрабатываю (в основном законченный) сценарий для группирования сеансов запуска для каждой из виртуальных машин.
Идея состоит в том, что функция скрипта, хранящая учетные данные, использует
read-host для запроса имени хоста, а затем get-credentials для выбора домена/пользователя/пароля.Затем проход преобразуется из secure-string с помощью 256-битного ключа (ключа времени выполнения, уникального для машины / пользователя, который хранил creds и запускал запуск группы).
Имя виртуальной машины, домен, пользователь и зашифрованный пропуск хранятся в файле. При запуске сеанса данные считываются, пароль расшифровывается, данные передаются в cmdkey.exe для хранения учетных данных generic:TERMSRV для этой виртуальной машины, очистить переменную передачи открытого текста, запустить mstsc для этого узла, через несколько секунд удалить учетные данные из хранилища учетных данных windows.
(Если я передал пароль в cmdkey.exe как что-либо другое, кроме открытого текста, сеанс RDP либо получит неверные учетные данные, либо их не будет).
Итак, отсюда вопрос, мне нужно пароль в открытом виде должен существовать в памяти как можно меньше времени.
Чтобы ребята из Службы безопасности были довольны, сам скрипт зашифрован aes256, а оболочка c# со своим собственным хостом ps читает, расшифровывает и запускает скрипт, поэтому на машине, которая его запускает, нет источника открытого текста. (Зашифрованный источник на файловом ресурсе так эффективно, что у меня есть переключатель kill, можно просто заменить зашифрованный скрипт на другой, отображающий сообщение о том, что это приложение было отключено)
5 ответов:
Вы можете использовать секундомер для получения времени выполнения командлетов. Я думаю, что на самом деле нет разницы во времени между этими двумя командлетами. Я использую обычно "Remove-Item", потому что в моих глазах лучше удалить переменную complete.
$a = "TestA" $b = "TestB" $c = "TestC" $d = "TestD" $time = New-Object system.Diagnostics.Stopwatch Start-Sleep 1 $time.Start() $time.Stop() $system = $time.Elapsed.TotalMilliseconds Write-Host "Stopwatch StartStop" $system $time.Reset() Start-Sleep 1 $time.Start() Clear-Item Variable:a $time.Stop() $aTime = $time.Elapsed.TotalMilliseconds - $system Write-Host "Clear-Item in " $aTime $time.Reset() Start-Sleep 1 $time.Start() Remove-Variable b $time.Stop() $bTime = $time.Elapsed.TotalMilliseconds - $system Write-Host "Remove-Variable in " $bTime $time.Reset() Start-Sleep 1 $time.Start() Clear-Item Variable:c $time.Stop() $cTime = $time.Elapsed.TotalMilliseconds - $system Write-Host "Clear-Item in " $cTime $time.Reset() Start-Sleep 1 $time.Start() Remove-Variable d $time.Stop() $dTime = $time.Elapsed.TotalMilliseconds - $system Write-Host "Remove-Variable in " $dTime $time.Reset()
Самый эффективный способ-позволить сборке мусора делать свою работу. Помните, что Powershell - это все .NET, со своим знаменитым управлением памятью. Всегда контролируйте свою область и убедитесь, что переменные выходят из области, как только они не нужны. Например, если временные переменные необходимы внутри циклов, они автоматически аннулируются в конце цикла, поэтому не нужно беспокоиться об этом и т. д.
EDIT: Что касается вашего обновления, почему бы просто не сделать
$yourPasswordVariable = $null? Я думаю, что это было бы намного проще. понимать. И это должен быть самый быстрый способ сделать это. ПосколькуRemove-ItemиClear-Itemявляются своего рода универсальными обработчиками, они должны сначала обработать некоторые вещи, прежде чем определить, что вы действительно хотите стереть переменную.
Единственный способ, которым я смог с уверенностью очистить переменные данные / содержимое, - это удалить все переменные, запущенные в текущем сеансе, используя:
Remove-Variable -Name * -ErrorAction SilentlyContinueЭто немедленно удаляет все переменные. Фактически, я добавляю это в конец некоторых моих сценариев, чтобы быть уверенным, что запуск другого сценария с потенциально тем же именем не приведет к добавлению новых данных и не приведет к нежелательным результатам.
Недостаток: Если вам нужно очистить только одну переменную, которая была в моем случае a несколько минут назад, то вам нужно повторно создать экземпляр входных переменных, необходимых для вашего скрипта.
Оба эффективно удаляют ссылку " a " на объект .NET. Теперь, если эта ссылка является последней ссылкой на объект, то GC определит, когда будет собрана память для указанного объекта. Однако если переменная больше не нужна, то используйте
Remove-Variable, чтобы также разрешить сбор памяти, связанной с объектомSystem.Management.Automation.PSVariable.
Чтобы измерить время, необходимое для запуска блоков сценариев и командлетов, используйте
Measure-Command
Comments