2012-12-08 2 views
5

런타임에 PowerShell 변수에 텍스트를 임시 저장하는 경우 더 이상 필요하지 않을 때 메모리에서 변수 내용을 제거하는 가장 효율적인 방법은 무엇입니까?Powershell - "Clear-Item 변수 :"vs "Remove-Variable"

내가 사용한 적이 모두 Clear-Item variable:Remove-Variable하지만 얼마나 빨리 뭔가 이전과 메모리 내용을 제로 화시키는 대 후반으로 메모리에서 제거됩니까?

편집 : 내가 왜 묻는 지 조금 더 명확하게해야했습니다.

많은 응용 프로그램 VM (응용 프로그램이 서비스, 아웃소싱 개발자, 긴 이야기로 실행되지 않음)에 대한 RDP 로그인을 자동화하고 있습니다.

그래서 각 VM에 실행 세션을 그룹화하는 스크립트를 개발 중입니다.

자격 증명을 저장하는 스크립트 기능은 read-host을 사용하여 호스트 이름을 묻는 메시지를 표시하고 get-credentials은 도메인/사용자/암호를 선택합니다.

그런 다음 패스는 256 비트 키 (creds를 저장하고 그룹 실행을 실행하는 시스템/사용자에게 고유 한 런타임 키)를 사용하여 secure-string에서 변환됩니다.

VM 이름, 도메인, 사용자 및 암호화 된 패스는 파일에 저장됩니다. 세션을 시작할 때 세부 정보를 읽고 암호를 해독하고 cmdkey.exe에 전달 된 세부 정보는 해당 VM에 대한 \generic:TERMSRV 자격 증명을 저장하고 plaintext 패스 변수를 지우고 해당 호스트에 mstsc를 실행하며 몇 초 후에 Windows 자격 증명 저장소에서 자격 증명을 제거합니다. (plaintext 이외의 다른 것으로 cmdkey.exe에 암호를 전달한 경우 RDP 세션에 잘못된 자격 증명이나 자격 증명이 제공되지 않음).

그럼, 질문, 가능한 한 짧은 시간 동안 메모리에 존재하는 일반 텍스트에서 암호가 필요합니다.

보안 담당자를 행복하게 유지하기 위해 스크립트 자체는 aes256으로 암호화되어 있으며 자체 ps 호스트가있는 C# 래퍼는 스크립트를 읽고 해독하고 실행하므로이를 실행하는 컴퓨터에 일반 텍스트 원본이 없습니다. (파일 공유에 암호화 된 소스가 너무 효과적이기 때문에 킬 스위치가있어 암호화 된 스크립트를이 앱이 비활성화되었다는 메시지를 표시하는 다른 것으로 간단하게 대체 할 수 있습니다)

답변

4

스톱워치를 사용하여 커맨드 릿의 실행 시간을 확보 할 수 있습니다. 나는이 두 cmdlet 사이에 실제로 시간차가 없다고 생각합니다. 저는 일반적으로 "Remove-Item"을 사용하고 있습니다. 왜냐하면 내 눈에는 변수를 완전히 제거하는 것이 더 낫기 때문입니다.

$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

사무실에있을 때 내 질문에 편집하여 속도가 중요한 이유를 확인해보십시오 :-) –

+2

특별한 경우에 필자의 권장 사항은 변수를 덮어 쓰는 것입니다. [System.GC] :: Collect()로 gc를 트리거 할 수는 있지만 이것은 좋은 생각이 아닙니다. 그래서 변수를 덮어 쓰는 것이 가장 좋은 해결책이라고 생각합니다 :-) – LaPhi

+0

은 감사의 말처럼 들립니다 .-) –

5

가장 효율적인 방법은 가비지 수집을 수행하는 것입니다. Powershell은 유명한 메모리 관리 기능을 갖춘 .NET입니다. 범위를 항상 제어하고 필요없는 변수가 범위에서 벗어나게하십시오. 임시 변수가 루프 내에서 필요한 경우 예를 들어, 그들은 자동으로 루프의 끝에서 등

EDIT 걱정 너무 필요, 무효화하지 않습니다 : 당신의 갱신에 대해서는을, 왜 단지 $yourPasswordVariable = $null는하지? 이해하는 것이 훨씬 쉬울 것이라고 생각합니다. 그리고 그것을하는 가장 빠른 방법이어야합니다. Remove-ItemClear-Item은 일종의 올인원 처리기이므로 변수를 먼저 지우려면 먼저 몇 가지 작업을해야합니다.

+0

사무실에있을 때 범위 지정으로 놀아 볼 것입니다. 내 질문에 맞게 편집하여 속도가 중요한 이유를 확인하십시오. :-) –

+1

@GrahamGold : 편집을 참조하십시오. – Neolisk

+0

Clear-Item 및 Remove-Variable이 어떻게 작동하는지 설명 할 때 멋지다. –

2

둘 다 .NET 개체에 대한 "a"참조를 효율적으로 제거합니다.이제 해당 참조가 객체에 대한 마지막 참조 인 경우 GC는 해당 객체에 대한 메모리가 수집되는시기를 결정합니다. 그러나 변수가 더 이상 필요하지 않으면 Remove-Variable을 사용하여 System.Management.Automation.PSVariable 개체와 관련된 메모리를 결국 수집 할 수도 있습니다.

+1

그 것이 핵심이라면, 하나 이상의 변수에 대해 GC를 즉시 실행하고 더 이상 메모리에 저장하지 않도록 할 수 있습니까? 왜 중요한지에 대한 정보는 EDIT를 참조하십시오. –

0

,이 스크립트 블록 및 cmdlet을 실행하는 데 걸리는 시간을 측정하는 변수 데이터를 삭제하기 위해, 확실하게, Measure-Command

+0

Command-Command가 측정 할 수있는 것이 아니라 명령이 실행 된 후 신속하게 메모리가 지워지는 것은 아닙니다. –

5

내가 할 수 있었다 유일한 방법을 사용하려면/컨텐츠는 현재에서 실행중인 모든 변수를 제거하는 것입니다 다음을 사용하는 세션 :

Remove-Variable -Name * -ErrorAction SilentlyContinue 

이렇게하면 모든 변수가 즉시 제거됩니다. 실제로이 스크립트를 일부 스크립트 끝에 추가하여 잠재적으로 같은 이름의 다른 스크립트를 실행해도 새 데이터가 추가되지 않아 원치 않는 결과가 발생할 수 있습니다.

DRAWBACK : 제 경우에는 몇 분 전인 한 변수 만 지우는 경우 스크립트에 필요한 입력 변수를 다시 인스턴스화해야합니다.