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, можно просто заменить зашифрованный скрипт на другой, отображающий сообщение о том, что это приложение было отключено)

620   5  

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

    Ничего не найдено.