2012-12-08 13 views
5

Podczas tymczasowego przechowywania tekstu w zmiennych programu Power Shell w czasie wykonywania, jaki jest najskuteczniejszy sposób usuwania zawartości zmiennych z pamięci, gdy nie są już potrzebne?Powershell - "Clear-Item zmienna:" kontra "Remove-Variable"

Użyłem zarówno Clear-Item variable:, jak i Remove-Variable, ale jak szybko coś zostanie usunięte z pamięci z tym ostatnim, a zerować zawartość pamięci z poprzednią?

EDYCJA: Powinienem był trochę wyjaśnić, dlaczego pytam.

Automatyzuję logowanie RDP dla kilku maszyn wirtualnych aplikacji (aplikacja nie działa jako usługa, outsourcing deweloperów, długa historia).

Opracowuję więc (w dużym stopniu skończony) skrypt do grupowania sesji uruchamiania na każdą z maszyn wirtualnych.

Pomysł polega na tym, że funkcja skryptu przechowująca referencje używa read-host, aby zapytać o nazwę hosta, a następnie get-credentials, aby odebrać domenę/użytkownika/hasło.

Przejście jest następnie konwertowane z bezpiecznego ciągu za pomocą klucza 256-bitowego (klucz runtime unikalny dla komputera/użytkownika, który przechowuje kredyty i uruchamia uruchomienie grupy).

Nazwa maszyny wirtualnej, domena, użytkownik i szyfrowane hasło są przechowywane w pliku. Podczas uruchamiania sesji szczegóły są odczytywane, odszyfrowywane, dane przekazywane do cmdkey.exe, aby przechowywać poświadczenia \generic:TERMSRV dla tej maszyny wirtualnej, wyczyścić zmienną przepustową tekstową, uruchomić mstsc dla tego hosta, kilka sekund później usunąć poświadczenie z magazynu referencji systemu Windows. (Jeśli przekazałem hasło do cmdkey.exe jako coś innego niż zwykły tekst, sesja RDP otrzyma niepoprawne dane lub nie będzie żadnych poświadczeń).

Tak więc, stąd pytanie, potrzebuję hasła W trybie zwykłego tekstu, aby istniało w pamięci tak krótko, jak to możliwe.

Aby zapewnić bezpieczeństwo użytkownikom, sam skrypt jest zaszyfrowany aes256, a opakowanie C# z własnym hostem ps odczytuje, odszyfrowuje i uruchamia skrypt, więc nie ma żadnego źródła tekstu w postaci zwykłego tekstu na komputerze, który to uruchamia. (Zaszyfrowane źródło w udziale plikowym tak skutecznie mam przełącznik zabicia, mogę po prostu zastąpić zaszyfrowany skrypt innym wyświetlającym komunikat, że ta aplikacja została wyłączona)

Odpowiedz

4

Możesz użyć stopera, aby uzyskać czas wykonania dla poleceń. Myślę, że nie ma różnicy czasu między tymi dwoma cmdletami. Używam normalnie "Remove-Item", ponieważ w moich oczach lepiej jest usunąć zmienną kompletną.

$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() 
+0

Będę się z tym bawić po powrocie do biura, zobacz EDYCJA na moje pytanie, aby zobaczyć, dlaczego prędkość ma znaczenie :-) –

+2

W twoim szczególnym przypadku moim zaleceniem jest nadpisanie zmiennej. Możesz wywołać gc za pomocą [System.GC] :: Collect(), ale nie jest to dobry pomysł. Myślę więc, że zastąpienie zmiennej jest najlepszym rozwiązaniem :-) – LaPhi

+0

brzmi jak droga, dzięki :-) –

5

Najbardziej efektywnym sposobem jest umożliwienie zbierania śmieci. Pamiętaj, że Powershell to wszystko .NET, ze słynnym zarządzaniem pamięcią. Zawsze kontroluj swój zakres i upewnij się, że zmienne wykraczają poza zakres, gdy tylko nie są potrzebne. Na przykład, jeśli zmienne tymczasowe potrzebne są wewnątrz pętli, będą one unieważnić na koniec pętli automatycznie, więc nie trzeba się martwić o to, itd

EDIT: dotycząceTwojego aktualizacji, dlaczego po prostu nie zrobić $yourPasswordVariable = $null? Myślę, że byłoby to łatwiejsze do zrozumienia. I powinien to być najszybszy sposób na zrobienie tego. Ponieważ Remove-Item i Clear-Item są rodzajami wielofunkcyjnych programów obsługi, muszą najpierw przetworzyć pewne rzeczy, zanim zdecydują, że naprawdę chcesz wymazać zmienną.

+0

Będę bawić się z zakresu po powrocie do biura, zobacz EDIT do mojego pytania, aby zobaczyć, dlaczego prędkość ma znaczenie :-) –

+1

@GrahamGold: zobacz moją edycję. – Neolisk

+0

Fajnie, ma sens, gdy wyjaśnisz, jak działa Clear-Item i Remove-Variable! –

2

Obie skutecznie usuwają odniesienie "a" do obiektu .NET.Jeśli to odniesienie jest ostatnim odniesieniem do obiektu, wówczas GC określi, kiedy pamięć dla tego obiektu zostanie zebrana. Jeśli jednak nie potrzebujesz już tej zmiennej, użyj opcji Remove-Variable, aby również umożliwić w ostatecznym przypadku także gromadzenie pamięci skojarzonej z obiektem System.Management.Automation.PSVariable.

+1

Myślę, że to jest sedno, jeśli możesz, możesz zmusić GC do natychmiastowego uruchomienia jednej lub więcej zmiennych i mieć pewność, że nie są już w pamięci? Zobacz EDYCJA dla informacji, dlaczego to ma znaczenie :-) –

0

Aby zmierzyć czas potrzebny do uruchomienia bloków skryptów i apletów poleceń, należy Measure-Command

+0

Tęskniłeś za punktem całkowicie - nie chodzi o szybkie uruchamianie polecenia cmdlet, ale o to, jak szybko pamięć zostanie wyczyszczona po wykonaniu polecenia - nie jest to coś, co można zmierzyć. –

5

Jedynym sposobem udało mi się, z pewnością, aby usunąć zmienne dane/treść jest usunąć wszystkie zmienne działające w prądzie sesja za pomocą:

Remove-Variable -Name * -ErrorAction SilentlyContinue 

Powoduje natychmiastowe usunięcie wszystkich zmiennych. W rzeczywistości dodaję to na końcu niektórych moich skryptów, aby mieć pewność, że uruchomienie innego skryptu o potencjalnie tej samej nazwie nie spowoduje dodania nowych danych i spowoduje niepożądane wyniki.

wadę: Jeśli potrzebne jest tylko jedną zmienną wyczyszczone, co było w moim przypadku kilka minut temu, to trzeba do ponownego wystąpienia zmiennych wejściowych wymaganych przez skrypt.

Powiązane problemy