윈도우 파워쉘 사용을 위한 10가지 팁

          



파워쉘은 커맨드 라인을 대체할 마이크로 소프트의 새로운 툴이다. 아직은 베터버전 이지만, 여기서 최신 버전을 무료로 다운로드 받을 수 있다. 우리같이 좀 묵은 사람들은 예전에 한때 DOS를 썼었고, 좀 지나서는 윈도우즈 환경에서 DOS 커맨드 창과 거의 비슷한 CMD.exe를 사용했다. 그러나 파워쉘은 DOS의 업데이트 버전이 아니다. 파워쉘은 MS가 이전에는 제공했던 어떤 커맨드 라인 프롬프트보다 강력한 커맨드라인 시스템이다. 안타깝게도 이 툴을 배우기 전에 해야 할 일이 있다. (역자: 파워쉘 설치와 함께 XP service pack 2.0 이상과 .NET 프레임워크 2.0이 설치되어 있어야 한다.) 툴을 설치하고 살펴본 후에는 아래의 10가지 팁을 읽어보아라. 여러분의 인생을 보다 편안하게 해줄 것이다. 

1. 일관성을 기억하라 

커맨드는 동사-명사의 형태로 되어있고 파라미터는 a- 로 시작한다는 것을 기억하라. 경로명에는 \ 과 / 을 모두 사용할 수 있다. 

파워쉘을 사용하는데 있어 가장 기본이 되는 규칙은 커맨드의 형식이 항상 동일한 형태로 되어있는 것이다. 이러한 특성을 기억하면 커맨드들을 기억하기가 한결 쉬울 것이다. 

동사-명사 구조의 예는 다음과 같다.
Set-Date
Write-Debug
Get-Item
Get-WmiObject

각각의 커맨드는 동사와 명사 사이에 하이픈으로 연결된다. 커맨드의 명사는 복수형을 써야 할 것 같은 상황이라도 단수형을 쓴다.
Get-Process
현재 동작 중인 모든 프로세스를 반환한다. (역자: 여러 프로세스를 가져올 것이지만, Get-Processes가 아닌 Get-Process로 사용한다.) 

일관성은 커맨드 명에만 해당하는 것은 아니다. 파라메터 역시 일관적이다. DOS나 Unix 세상에서는 커맨드에서 - 나 / 모두 파라메터를 의미했다. 그러나 파워쉘에서는 모든 파라메터는 - 으로 시작한다. 하지만 경로명에서는 / (forward slash) 나 \ (backward slash) 모두 사용될 수 있다. 더 편하다고 느끼는 것을 사용하면 된다. 경로를 조합해야 할 경우가 있다면 내장된 커맨드인 join-path를 다음과 같이 사용하면 된다.
join-path c:\ \temp
결과는 C:\temp 가 된다. 

(이것은 두 문자열을 합칠 때 여러분이 중복된 slash를 직접 지우지 않아도 되기 때문에 편리하다.) 

2. 유용한 명령어를 기억하라 

커맨드 리스트를 보기위해 Get-Command를 사용하고 커맨드의 사용법을 알기위해서는 Get-Help를 써라. 또한 -? 파라미터를 써서 커맨드의 사용법을 알아낼 수 있다. TabExpansion을 사용해라 (그리고 TabExpansion을 대체할 것을 찾아보아라). 

새로운 언어를 쓰게 될 때 여러분은 우선 그 어휘를 알려고 할 것이다. 파워쉘 두 번째 배포에서는 129개의 명령어가 포함되었다. 129개는 배우기에 너무 부담스럽고 기억하기 어렵다. 그러나 여러분이 최소한 어떤 명령어가 사용 가능한지 알고 모든 커맨드 리스트를 보고 싶다면 이렇게 입력하라.
Get-Command
그리고 Get-Help가 있는데, Get-Help는 특정한 커맨드의 사용법을 알려준다.
Get-Help Get-Member
는 커맨드 Get-Members에 대한 도움말을 보여준다. 또는 다음과 같이 -? 파라미터를 전달할 수 있다.
Get-Member -?
이 내장 커맨드는 또한 다른 레벨의 설명을 제공한다. 기본 설명은 기초적인 정보를 보여준다. Get-Help에 -detailed를 파라메터로 붙여 상세한 설명을 제공받을 수 있다.
Get-Help Get-Member -detailed
여기에 더욱 보강된 설명을 얻고자 하면 -full을 사용한다.
Get-Help Get-Member -full
대다수의 커맨드들이 상당히 긴데, 우리 컴퓨터 족들은 보통 긴 명령어를 싫어한다. 그래서 파워쉘은 커맨드의 별칭들을 제공한다. 다음과 같은 모든 별칭의 리스트를 볼 수 있다.
PS C:\WINDOWS\system32> Get-Alias

CommandType     Name            Definition
-----------     ----            ----------
Alias           ac              Add-Content
Alias           asnp            Add-PSSnapin
Alias           clc             Clear-Content
Alias           cli             Clear-Item
Alias           clp             Clear-ItemProperty
...
원하는 커맨드를 찾을 때 Tab 키는 특별한 기능을 제공한다. 만약 동사를 기억한다면 동사와 하이픈를 입력하고 Tab을 반복해서 누르면 해당하는 동사로 시작하는 명령어가 자동으로 입력되며 순환한다. 만약 아래와 같이 입력했다면,
Get-
Tab을 눌러보아라. Get-Acl, Get-Alias, Get-AuthenticodeSignature 등등 명령어를 보게 될 것이다. Tab 표현식은 유연한 편이 바람직한데, MS도 이를 알고 있기 때문에 Tab표현식을 수정할 수 있게 하였다. 인터넷에서 PowerShell TabExpansion(Tab과 Expansion사이에 공백을 넣지 말 것)에 대해서 검색해보면 정보를 찾을 수 있을 것이다. 다른 사람들이 이미 Tab 표현식을 작성해 놓은 것이 있는데, 일부는 꽤 유용하다. 그 중에서 필요한 것을 찾아 사용하면 된다. (추가적으로, Get-Content function:TabExpansion을 사용하면 TabExpansion function의 소스를 볼 수 있다.) 여기 필자가 자주 사용하는 몇몇 커맨드를 나열했다. 커맨드를 사용할 때, 아마도 사용할 수 있는 별칭에 대해서도 알고 싶을 것이다.. 

커맨드 별칭 

커맨드별칭
Copy-Itemcpi, cp, copy
ForEach-Objectforeach, %
Get-ChildItemdir, ls
Get-Commandgcm
Get-Contentcat, type
Get-Contentgc, type, cat
Get-Helphelp
Get-Locationgl, pwd
Move-Itemmi, mv, move
Remove-Itemri, rd, del, rm, rmdir
Rename-Itemrni, ren
Set-Locationcd, chdir
Where-Objectwhere

Get-Command는 필요한 커맨드를 찾기 위한 파라메터를 지원한다. 이를테면 커맨드에 Format이라는 단어가 들어간 것들을 찾고자 한다면, 다음과 같이 입력한다.
Get-Command *Format*
동사 Format으로 시작되는 커맨드를 찾고싶을 수도 있다 (Format-Table과 같이). 그럴 때는 이렇게 입력한다.
Get-Command -verb Format
동사가 정확히 Format인 커맨드인 명령어를 반환할 것이다. 만약 아래와 같이 입력하면,
Get-Command -verb Form
아무런 결과도 얻지 못할 것이다. 이럴 때는 와일드카드 형식을 쓴다:
Get-Command -verb Form*
유사하게 명사에 대해서도 적용 할 수 있다.
Get-Command -noun Alias
Alias라는 단어가 들어가는 커맨드를 확인할 수 있을 것이다.. 

간단한 한 문자 별칭이 두 개 있는데, %는 ForEach-Object의 별칭이고 ?는 Where-Object의 별칭이다. 

3. 기본 타입과 내장 변수 배우기 

기본 타입과 파서가 그것을 어떻게 인지 하는지 배워보자. 정규 표현식을 마스터 하면 여러분 인생이 완전해질 것이다.. 파워쉘 스크립트 언어는 몇 개의 유용한 기본타입을 지원한다. 그리고 그러한 타입의 변수를 생성할 수 있다. 여기에는 문자열, 숫자, 배열과 사전형(Hash나 Map으로도 알려져 있는)이 있다. .NET에서 기본적으로 지원하는 타입은 모두 사용할 수 있다고 보면 된다. (다음 섹션에서 .NET에 대해서 이야기해 보겠다) 

커맨드 분석기는 입력하는 내용에 따라 타입을 결정한다. 만약 당신이 다음을 입력하면
5
당신은 숫자형을 선언한 것이다. 변수 이름은 $로 시작하며 숫자를 다음과 같이 저장할 수 있다.
PS C:\> $a = 5
PS C:\> $a
5
PS C:\>
GetType()을 호출하여 내장된 .NET 타입을 알아낼 수 있다.
PS C:\> $a.GetType()
IsPublic IsSerial Name              BaseType
-------- -------- ----              --------
True     True     Int32             System.ValueType
파서는 또한 다른 기본 타입도 알아낼 수 있다. 더블형은 소수점을 이용해 만들어 진다.
PS C:\> $b = 3.1415926
PS C:\> $b
3.1415926
PS C:\> $b.GetType().Name
Double
오늘날의 대다수의 스크립트 언어와 마찬가지로 스트링에 외 따옴표와 겹 따옴표를 모두 사용할 수 있다. 이는 몇몇 문제 상황에 편리한데, 이를테면 스트링에 겹 따옴표가 있으면 스트링 자체는 외 따옴표로 정의한다.
$c = '<span style="border:1px solid none">'
배열을 생성하기 위해서는 단지 항목을 구분하는 콤마를 쓰면 된다.
PS C:\> $d = 1,2,3,"Hello"
PS C:\> $d
1
2
3
Hello
PS C:\> $d.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

필요하다면 배열 주위를 괄호로 묶을 수 있다. 이것은 배열 안에 배열을 넣을 때 유용하다.
$e = (1,2,3,(4,5,6))
숫자의 범위는 .. 연산자를 사용하여 다음과 같이 지정할 수 있다.
$f = 1..5
1,2,3,4,5를 포함하는 배열이 생성될 것이다. 

사전형을 생성하기 위해서는 @를 다음과 같이 사용한다.:
PS C:\> $myhash = @{ 'one'=1; 'two'=2; 'three'=3 }
PS C:\> $myhash

Name                           Value
----                           -----
two                            2
three                          3
one                            1

PS C:\> $myhash['one']
1
PS C:\> $myhash['four']
PS C:\>
.NET은 강력한 정규 표현식을 지원하기 때문에, 파워쉘 역시 regex 타입을 지원한다. 정규 표현식을 생성하기 위해서는 대괄호([ ]) 안에 regex를 넣고 뒤에 문자열을 덧붙인다. 그러면 -match 연산자를 이용하여 정규 표현식을 사용할 수 있다. 

여기 예문이 있다.
PS C:\> $re = [regex]"abc[123]"
PS C:\> "abc1" -match $re
True
PS C:\> "abc4" -match $re
False
PS C:\>
만약 정규 표현식에 익숙치 않다면 지금이 배워야 할 때이다. 다른 프로그래밍 언어도 그렇지만, 정규 표현식을 많이 알수록 파워쉘을 더욱 쉽게 쓸 수 있다. 자주 사용하는 검색엔진으로 가서 "정규 표현식 배우기"라고 입력해봐라. 괜찮은 페이지가 몇 개 나올 것이다. 그렇지만 가장 좋은 자료는 제프리 프리들이 저술한 오렐리의 정규 표현식 완전 해부와 실습(Mastering Regular Expressions) 이다. 

이 책은 모든 컴퓨터 프로페셔널들이 읽어야 할 몇 안 되는 필독서다. 

쉘은 몇 가지 변수를 기본으로 내장 한다. 여기에 일부를 나열한다.
  • $$: 이전 줄의 마지막 토큰
  • $?: 마지막으로 성공이나 실패 상태
  • $^: 이전 줄의 첫번째 토큰
  • $pshome: 파워쉘이 설치된 디렉터리. 이 변수는 types.ps1xml같이 설정 관련 파일을 조작할 때 편리하다. 예를 들면,
    scite (join-path $pshome types.ps1xml)
(Scite는 내가 애용하는 공짜 텍스트 에디터다.) 

특정 구문에 의존하지 않는 타입을 원한다면, 파워쉘이 지원하는 바로 가기 타입을 이용하면 된다. 바로 가기 타입은 타입이름을 줄인 것으로 마이크로소프트 파워셀 블로그에 가면 그 리스트를 볼 수 있다. 타입을 배우고 익히는 것은 어렵다고 느낄 수 있다. 특히 커맨드가 생소한 타입의 오브젝트를 반환할 때는 더욱 그럴 것이다. 온라인 도움말을 잘 이해할 수 있다면 이 블로그를 방문해 보자. 모든 오브젝트 타입에 대한 설명을 볼 수 있어 파워쉘 실력을 키우데 많은 도움이 될 것이다. 

(만약 이것을 바꾸려거든 파일을 갱신해야 할 것이다. 팁 "개인 환경 설정하기"를 찾아보면 자세한 정보를 얻을 수 있다.) 이것을 변경할 때 어떤 오브젝트 타입에 대한 온라인 도움말도 찾을 수 있을 것이다. 그 기법은 완벽하지도 않고 모든 오브젝트에 대해 통하지도 않지만 대부분의 경우에는 잘 동작한다.. 

4. .NET 알기 

.NET 프레임워크는 파워쉘이 동작하는데 기반이 된다. .NET에 대해 잘 알게 된다면 독자의 파워쉘 내공도 한층 높아질 것이다.. 

파워쉘을 최대한 잘 사용하려면 .NET 프레임워크와 친해져야 한다. .NET 프레임워크에 대한 모든 설명은 온라인에서 구할 수 있다. .NET문서의 시스템 부분까지 이동해보자. 여기서 Int32, String, Array같은 기본 타입에 대한 설명을 찾아 볼 수 있다. 

간단히 말해서 .NET 프레임워크는 파워쉘 작업 중에 사용 할 수 있는 클래스와 타입들의 집합체라고 할 수 있다. 타입을 많이 알아두면 좋다. 타입들의 목록을 보면 해당 오브젝트로 할 수 있는 것을 알 수 있다. 이를테면 시스템 페이지를 클릭하고 스트링을 클릭하면 스트링 클래스의 목록을 얻을 수 있다. 

대부분의 커맨드는 .NET 오브젝트(혹은 오브젝트의 집합)을 반환한다. 예를 들어 Get-Date 커맨드는 화면에 현재 날짜와 시간을 출력할 것이다. 하지만 사실은 커맨드가 DateTime이라는 .NET 프레임워크의 타입을 반환한 것이다. 마찬가지로 Get-ChildItem(혹은 별칭인 dir)을 타이핑하면 디렉터리 리스트가 출력되지만 실제로는 .NET 프레임워크의 DirectoryInfo나 FileInfo 오브젝트의 집합을 보는 것이다. 

.NET 프레임워크는 거대한 계층으로 구성되어 있으며, 모든 클래스는 Object로부터 파생된다. Object 클래스는 .NET의 모든 클래스에 기본적이며 공통된 기능을 제공한다. 예를 들면 ToString 이라는 함수이다. 이 함수는 오브젝트를 표현할 수 있는 텍스트를 반환한다. 따라서 파워쉘의 어느 객체에 대해서도 이 함수를 호출하여 오브젝트를 표현하는 텍스트를 얻을 수 있다. (사실 정확히 말하자면 파워쉘이 오브젝트를 콘솔에 출력하는 방법을 의미한다) 

5. 파이프라인이 텍스트 기반이 아닌 오브젝트 기반이라는 것을 이해하라 

오브젝트가 단순히 텍스트를 통해서가 아니라 파이프라인을 통해서 진행된다는 것을 기억하라. 이는 파이프의 어떠한 시점에서도 세부적인 정보를 얻는 것이 가능하다는 것을 의미한다. 

만약 윈도우즈의 cmd나 다른 유닉스 계열의 쉘 같이 다른 쉘을 이용해본 적이 있다면 텍스트를 출력하는 커맨드가 다른 커맨드로 내용을 전달 할 수 있다는 것을 알 것이다. 예를 들면 cmd와 DOS의 dir 커맨드는 파일 리스트를 출력한다. 이 리스트가 텍스트의 형태다. 단순히 dir을 입력하면 윈도우 콘솔 화면에서 파일 리스트를 보게 될 것이다. 그러나 리스트를 화면에 출력하는 대신에 다른 커맨드에 입력으로 넣을 수 있다. 이것을 파이핑 이라고 부른다. more 커맨드는 텍스트를 읽거나 한 페이지 분량씩 출력하고 대기 하다가 키 입력이 있으면 다음 페이지를 보여주는 기능을 한다.
C:\WINDOWS >dir /ad | more
 Volume in drive C has no label.
 Volume Serial Number is BCFB-2313

 Directory of C:\WINDOWS

11/04/2006  10:59 PM    <DIR>          .
11/04/2006  10:59 PM    <DIR>          ..
06/07/2004  07:03 PM    <DIR>          $NtUninstallKB824105$
06/07/2004  07:05 PM    <DIR>          $NtUninstallKB824141$
10/15/2004  09:06 PM    <DIR>          $NtUninstallKB824151$
06/07/2004  07:01 PM    <DIR>          $NtUninstallKB825119$
06/07/2004  07:00 PM    <DIR>          $NtUninstallKB828035$
06/07/2004  06:58 PM    <DIR>          $NtUninstallKB828741$
06/07/2004  06:59 PM    <DIR>          $NtUninstallKB833407$
-- More  --
사람들은 이러한 파이프가 텍스트를 다루는데 막강한 유틸리티 라는 것을 알게 되었다. 몇 년 전에 awk와 grep이 개발되었고 이를 이용해서 텍스트를 처리하게 되었다. (awk는 공백으로 구분되는 레코드 파일로부터 조건을 만족하는 결과를 쉽게 얻을 수 있다. grep은 텍스트에서 패턴을 만족하는 부분을 찾을 수 있으며 현재까지도 많이 사용된다) 현재에 이르러서는 Perl 같은 훨씬 강력한 텍스트 처리 언어를 사용한다. 

DOS의 dir과 같이 간단한 커맨드가 텍스트를 이용하는 반면 보다 강력한 툴들은 오브젝트를 활용한다. 만약 윈도우즈 시스템에서 여러 개의 프로세스를 관리한다고 할 때 프로세스 하나는 텍스트 한 줄을 뜻하는 것은 아니다. 여기서 프로세스는 프로세스 ID나 보안 설정 값 등으로 구성된 하나의 오브젝트다. 이러한 것은 단순한 텍스트 이상의 것이다. 

만약 어떤 툴이 여러 프로세스를 가져와서 그 정보를 단순한 텍스트로 다른 툴에게 넘긴다면 정보를 넘겨 받은 툴은 속은 것이다. 그 툴은 실제 오브젝트가 아닌 단순한 프로세스의 텍스트 기반 정보를 얻은 것이다. 

더 좋은 방식은 간단하게 첫번째 툴이 두 번째 툴에게 실제 오브젝트를 전달(pipe)하는 것이다. 툴은 결국 텍스트를 출력하는 윈도우를 다루어야 하기 때문에 처음엔 문제인 것처럼 보일 수도 있다. 그렇지만 dir | more처럼 커맨드가 함께 동작하는 것을 생각해 보면 마지막으로 콘솔 윈도우에 출력되는 것은 단순한 출력 이상의 것이다. dir에서 more로 정보가 전달되는 것은 전혀 콘솔에 표시되지 않는다. 

여기 예가 있다.
PS C:\WINDOWS> dir | sort LastWriteTime | more


    Directory: Microsoft.PowerShell.Core\FileSystem::C:\WINDOWS


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---          7/4/1995   1:33 PM      11776 Ckrfresh.exe
-a---         7/31/1995   5:44 PM     212480 PCDLIB32.DLL
-a---          5/3/1996  10:36 AM      18432 Setup_ck.dll
-ar--          5/3/1996  12:21 PM      27648 Setup_ck.exe
-a---         7/22/1998  12:29 AM         21 CS_SETUP.ini
-a---        10/29/1998   3:45 PM     306688 IsUninst.exe
-a---         1/12/1999  10:39 AM       6656 delttsul.exe
-a---         1/12/1999  10:40 AM      29184 rmud.exe
-a---         6/18/1999   4:49 PM     165888 Ckconfig.exe
-a---        11/10/1999   3:05 PM      86016 unvise32qt.exe
...

(dir은 Get-Children의 별칭이고 sort는 Sort-Object의 별칭이다. 그리고 more는 Out-Host -paging을 호출한다. 따라서 dir | sort LastWriteTime | more는 Get-Children | Sort-Object | Out-Host -Paging.을 줄인 것이다.) 

예에서 보이는 목록은 디렉터리를 LastWriteTime 필드로 정렬하고 한 페이지씩 출력하고 있다. 하지만 오브젝트들은 파이프라인으로 전달 된 후 마지막엔 결국 텍스트로 바뀌었기 때문에 아래와 같이 입력해서 결과를 변수에 저장할 수 있다.
PS C:\WINDOWS> $a = dir | sort LastWriteTime
변수 $a는 지금 Sort-Object 커맨드의 결과를 담고 있는데 $a의 내용은 단순한 텍스트가 아니다. dir(Get-ChildItem) 커맨드는 FileInfo와 DirectoryInfo 오브젝트의 리스트를 리턴받아 sort (Sort-Object) 커맨드에 전달했다. 따라서 $a는 FileInfo와 DirectoryInfo 오브젝트의 리스트이다. 아래와 같이 대괄호를 이용해서 각각의 원소에 접근할 수 있다.
PS C:\WINDOWS> $a[0]

    Directory: Microsoft.PowerShell.Core\FileSystem::C:\WINDOWS

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---          7/4/1995   1:33 PM      11776 Ckrfresh.exe


PS C:\WINDOWS> $a[1]

    Directory: Microsoft.PowerShell.Core\FileSystem::C:\WINDOWS

Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---         7/31/1995   5:44 PM     212480 PCDLIB32.DLL
다음 섹션에서 오브젝트의 멤버함수 호출에 대해서 더 자세히 다루겠다. 여기서는 GetType() 함수를 호출해서 해당 오브젝트(단순한 텍스트가 아닌)의 타입을 알아보자. 아래는 내가 변수 $a 의 타입을 알아본 것이다.
PS C:\WINDOWS> $a.GetType()

IsPublic IsSerial Name                BaseType
-------- -------- ----                --------
True     True     Object[]            System.Array
오브젝트 $a는 배열이다. 이제 첫번째 원소가 무엇인지 알아보자.
PS C:\WINDOWS> $a[0].GetType()

IsPublic IsSerial Name                BaseType
-------- -------- ----                --------
True     True     FileInfo            System.IO.FileSystemInfo
6. 오브젝트 활용하기 

파이프를 통해 전달되는 오브젝트는 클래스가 형상화된 것이다. 여러분들은 오브젝트의 데이터와 함수를 활용할 수 있다. 

커맨드의 리턴으로 받은 오브젝트를 포함해서 모든 오브젝트의 멤버를 이용할 수 있다는 것을 잊지 말아라. Get-Member 커맨드를 이용해서 오브젝트의 멤버를 알아낼 수 있다.
PS C:\Documents and Settings\Jeff> $a = "abc"
PS C:\Documents and Settings\Jeff> Get-Member -InputObject $a


   TypeName: System.String

Name             MemberType            Definition
----             ----------            ----------
Clone            Method                System.Object Clone()
CompareTo        Method                System.Int32 CompareTo(Object value),...
Contains         Method                System.Boolean Contains(String value)
CopyTo           Method                System.Void CopyTo(Int32 sourceIndex,...
EndsWith         Method                System.Boolean EndsWith(String value)...
...
특정 커맨드의 결과를 파이프로 Get-Member에 넘기면 Get-Member는 커맨드가 리턴한 오브젝트의 멤버 리스트를 보여줄 것이다. 같은 타입인 두 오브젝트가 넘겨지는 경우에는 Get-Member는 타입에 대한 멤버의 목록을 한번만 보여줄 것이다. 예를 들어 당신이 Get-Process 커맨드로 리턴 받은 오브젝트의 멤버에 대해서 알고싶다고 하자. 그러면 파이프로 Get-Member에게 아래와 같이 전달한다.
PS C:\Documents and Settings\Jeff> Get-Process | Get-Member


   TypeName: System.Diagnostics.Process

Name                           MemberType     Definition
----                           ----------     ----------
Handles                        AliasProperty  Handles = Handlecount
Name                           AliasProperty  Name = ProcessName
NPM                            AliasProperty  NPM = NonpagedSystemMemorySize
PM                             AliasProperty  PM = PagedMemorySize
VM                             AliasProperty  VM = VirtualMemorySize
WS                             AliasProperty  WS = WorkingSet
add_Disposed                   Method         System.Void add_Disposed(Event...
add_ErrorDataReceived          Method         System.Void add_ErrorDataRecei...
...
Where-Object 커맨드는 주로 파이프라인에서 사용되며 정의된 기준을 만족하는 오브젝트만을 통과시킨다. 필터링 기준을 정의하여 파이프라인을 통과한 오브젝트의 멤버에만 접근하게 된다. 

이를테면 여기에 전체 출력을 보이지는 않았지만 Get-Process | Get-Member는 Get-Process의 결과로 VirtualMemorySize라는 멤버를 갖는 각각의 오브젝트를 보여준다. 만약 당신이 VirtualMemorySize가 100 MB (정확히는 104,857,600 bytes) 이상인 프로세스의 리스트를 보고싶다고 하자. 이런 경우 아래와 같이 할 수 있다.
PS C:\Documents and Settings\Jeff> Get-Process | Where-Object {$_.VirtualMemorySize -gt 104857600}

Handles  NPM(K)    PM(K)      WS(K) VM(M)   CPU(s)     Id ProcessName
-------  ------    -----      ----- -----   ------     -- -----------
    948      15    38928      52788   346    12.23    712 dexplore
    256      10    72624      81592   194   136.00   2664 firefox
    350      14    30948      44268   133     7.06   3576 OUTLOOK
    309       8    31928       6404   833   221.14    356 sqlservr
    334       9    22188      14784   817     0.53    852 sqlservr
   1598      91    18668      27404   142   156.75   1864 svchost
    356      24    15708      23740   169   201.47   1536 WINWORD
Where-Object 커맨드는 스크립트의 중괄호 안에 파라메터 값을 취한다. 그 스크립트는 파이프라인으로 넘겨받는 모든 오브젝트 대해 수행된다. 넘겨진 오브젝트 들은 변수 $_ 에 대입된다. 따라서 $_.VirtualMemorySize는 현재 파이프라인에 있는 오브젝트의 멤버 VirtualMemorySize를 가리킨다. -gt는 ~ 보다 크다는 비교 연산자다. 따라서 현재 오브젝트의 가상 메모리 크기가 100 MB보다 큰지 아래와 같이 테스트 할 수 있다.
Get-ChildItem | foreach { $_.Fullname }
지금까지 보았듯이 오브젝트의 멤버들에 익숙해져야 한다. 관련 내용은 온라인 도움말을 이용해서 찾아볼 수 있다. 온라인 도움말로 이동했으면 우선 시스템을 클릭하고 다시 스트링을 클릭하면 이제 스트링 클래스의 도움말 페이지에 도달해있을 것이다. 페이지의 하단부(왼쪽 창의 트리안)에 String Members라는 항목이 있다. 그 페이지는 스트링 클래스의 모든 멤버 리스트를 보여준다. 

예를들면 EndsWith라는 멤버가 있다. 이 멤버는 스트링의 끝이 주어진 문자 집합의 문자로 끝나는지의 여부를 알려준다. 

여기 예문이 있다.
PS C:\> $a = "This is a test"
PS C:\> $a.EndsWith("test")
True
PS C:\> $a.EndsWith("this")
False
PS C:\>
7. 출력 형식 

다양한 Format-커맨드를 이용해서 출력 형식을 구미에 맞게 변경할 수 있다. 

파워셀은 파이프라인을 통해서 오브젝트를 전달한다. 다만 화면출력을 해야 하는 경우에만 오브젝트의 텍스트 버전을 얻는다. Get-Process를 실행해서 나온 오브젝트의 멤버 목록을 본다면 출력되는 것 보다 많이 볼 수 있을 것이다. 어떤 멤버가 출력될까? 그 답은 시스템 설정에 있다. 파워쉘 디렉터리를 들여다 보면 dotnettypes.format.ps1xml라는 파일이 있다. 이 XML파일은 다양한 타입의 출력 형식을 정의한다. 디렉터리 내에는 각각의 타입을 정의하는 *.format.ps1xml의 형식의 파일이 몇 개 있다. 이것에 관해서는 여기서 더 배울 수 있다. 

출력 형식을 설정하기 위해 파워쉘 유저는 FormatTable이라는 커맨드를 사용한다. 이 커맨드는 오브젝트의 파이브라인을 취하며, 형식이 정의되 있는 *.format.ps1xml 파일을 이용한다. 다음과 같이 세팅을 오버라이딩 하고 멤버를 선택해서 화면에 출력할 수 있다.
Get-Process | Format-Table Id, Name
  Id Name
  -- ----
2876 alg
 532 ApntEx
2044 Apoint
3448 calc
1824 CFSvcs
2176 cmd
3760 cmd
1640 Crypserv
1316 csrss
위의 결과는 기본 세팅을 무시하고 테이블의 ID와 Name 컬럼을 출력한 것이다. 

파워셀에는 4개의 형식 커맨드가 있다.
  • Format-Custom
  • Format-List
  • Format-Table
  • Format-Wide
Get-Help 명령을 써서 각각의 명령에 대해 알아볼 수 있다. 

8. 모든 것은 계층화 되어있다 

파워쉘 드라이브는 단순히 파일 시스템 이상의 것이다. 레지스트리, 환경 그리고 다른 데이터에 드라이브로서 접근할 수 있다. 컴퓨터를 계층적으로 정의하는 것은 오래 전부터 나온 개념이다. 이를테면 유닉스는 하드웨어를 항상 계층형 파일시스템의 일부로 다뤄왔다. 유사하게 파워쉘은 컴퓨터의 다양한 부분을 드라이브로 다룬다. 아래와 같이 Get-PSDrive 커맨드를 사용하면 현재 어떠한 드라이브가 가능한지 볼 수 있다.
PS C:\Documents and Settings\Jeff> Get-PSDrive

Name       Provider      Root                       CurrentLocation
----       --------      ----                       ---------------
Alias      Alias
C          FileSystem    C:\                        Documents and Settings\Jeff
cert       Certificate   \
D          FileSystem    D:\
Env        Environment
Function   Function
HKCU       Registry      HKEY_CURRENT_USER
HKLM       Registry      HKEY_LOCAL_MACHINE
Variable   Variable

예를 들면 Alias는 별칭의 리스트를 의미하는 드라이브다. 아래와 같이 원하는 어느 드라이브로든 변경할 수 있다.
PS C:\WINDOWS\system32> cd alias:
PS Alias:\>
PS Alias:\> dir

CommandType     Name                  Definition
-----------     ----                  ----------
Alias           ac                    Add-Content
Alias           asnp                  Add-PSSnapin
Alias           clc                   Clear-Content
Alias           cli                   Clear-Item
Alias           clp                   Clear-ItemProperty
Alias           clv                   Clear-Variable
Alias: 드라이브는 하위 디렉터리를 지원하지 않지만 Registry 같은 경우에는 지원한다.
PS Alias:\> cd HKCU:
PS HKCU:\> dir

   Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER

SKC  VC Name                           Property
---  -- ----                           --------
  2   0 AppEvents                      {}
  1   0 CLSID                          {}
  4  32 Console                        {ColorTable00, ColorTable01, ColorTab...
 24   1 Control Panel                  {Opened}
  0   8 Environment                    {BAKEFILE_PATHS, INCLUDE, LIB, PROMPT...
  0   1 HBA                            {Version}
  1   5 Identities                     {Identity Ordinal, Migrated5, Last Us...
  3   0 Keyboard Layout                {}
  0   0 Movie Magic Screenwriter       {}
 19   0 Movie Magic Screenwriter Vo... {}
  0   0 Network                        {}
  1   1 Note-It                        {(default)}
  4   1 Printers                       {DeviceOld}
  1   1 RemoteAccess                   {InternetProfile}
  1   7 S                              {AutodiscoveryFlags, DetectedInterfac...
100   1 Software                       {(default)}
  0   0 UNICODE Program Groups         {}
  2   0 Windows 3.1 Migration Status   {}
  1   0 Win_32                         {}
  0   1 SessionInformation             {ProgramCount}
  0   7 Volatile Environment           {LOGONSERVER, CLIENTNAME, SESSIONNAME...


PS HKCU:\> cd Software\Microsoft
PS HKCU:\Software\Microsoft> dir


   Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microso
ft

SKC  VC Name                           Property
---  -- ----                           --------
  1   0 Active Setup                   {}
  3   0 ActiveMovie                    {}
  2   0 Advanced INF Setup             {}
  1   0 ASF Stream Descriptor File     {}
  1   0 Automap                        {}
  1   4 Broadband Networking           {StatusTimeout, InternetStatusTimeout...
  1   1 ClipArt Gallery                {UserAdded}
  0   5 Clipbook                       {WindowsClipBook Viewer, WindowsClipb...
  0   2 Clock                          {iFormat, {CCF5A555-D92E-457b-9235-2B...
DOS에서처럼 여기서도 파일명에 패턴을 쓸 수 있다.
PS HKCU:\Software\Microsoft> dir *windows*


   Hive: Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microso
ft

SKC  VC Name                           Property
---  -- ----                           --------
  3   0 Windows                        {}
  0   1 Windows Genuine Advantage      {code}
  0   5 Windows Help                   {Maximized, Xl, Xr, Yd...}
  1   0 Windows Media                  {}
  1   0 Windows NT                     {}
  1   0 Windows Script                 {}
  1   0 Windows Script Host            {}
?는 문자 하나와 매칭된다. 예를 들면 abc? 는 abc로 시작하며 뒤에 문자 하나가 붙은 문자열과 매치된다. 대괄호를 써서 매치할 문자열을 정의할 수도 있다. abc[123]은 abc1, abc2, 그리고 abc3과 매치된다. 

9. 흐름과 스크립트를 사용해라 

파워셀은 강력하며 스크립트를 지원하는 언어다. 

많은 커맨드가 스크립트를 파라메터로 취한다. Where-Object가 한 예이다. 이전에 아래 코드를 본적이 있을 것이다.
Get-Process | Where-Object {$_.VirtualMemorySize -gt 104857600}
For-Each 오브젝트는 리스트의 각각 아이템에 대하여 스크립트를 실행시킨다. 

간단한 예제를 보자.
PS C:\WINDOWS\system32> 1..10 | foreach { $_ * 2 }
2
4
6
8
10
12
14
16
18
20
이것만으로는 별로 유용한 예제는 아닌 듯하다. 이러한 기법은 다양하게 응용될 수 있다. 이를테면 디렉터리 내의 첫번째 줄에 "#backup"이라는 문자열이 들어가는 모든 txt 파일을 C:\backups 디렉터리로 복사할 수 있다. 

한번 해보자.
dir *.txt | foreach { if ((Get-Content $_ -totalCount 1) -eq "#backup") { copy $_ c:\backups } }
우선 dir 커맨드의 결과가 파이프를 통해서 foreach 커맨드로 보내진다. foreach 커맨드는 각 항목마다 중괄호로 쌓여진 스크립트를 실행한다. 이 스크립트는 각 파일의 첫번째 줄을 읽어서(Get-Content의 -totalCount 1 은 첫번째 줄만 허용) #backup과 비교한다. 만약 문자열이 맞으면 스크립트는 그 파일을 복사한다. 

10. 개인 환경을 구축해라 

profile.ps1 파일을 수정해서 각자의 입맛에 맞게 환경을 세팅 할 수 있다. 

여러분들이 필요한 일을 수행하기 위해서 스크립트를 작성하고 나서는 나중을 위해서 그것을 보관하려고 할 것이다. 또한 기억하기 편하도록 명령어 몇 개에 별칭을 생성하고 싶어할 수 있다. 예를 들면 이전섹션에서 #backup이 들어가는 txt 파일을 저장하는 스크립트를 만들었다. 그것을 각자의 프로파일에 추가할 수 있다. 먼저 해당 스크립트는 아래와 같이 function 형식으로 만들어야 한다.
function Backup-TextFiles {
    dir *.txt | foreach {
        if ((Get-Content $_ -totalCount 1) -eq "#backup") { 
            copy $_ c:\backups } 
        }
    }
이 함수를 프로파일에 추가한다. 프로파일은 각자의 홈 디렉터리에 있는 Profile.ps1이라는 파일이다. 홈 디렉터리는 \Documents and Settings\<username>\My Documents\WindowsPowerShell\profile.ps1이며, <username>은 각자의 실제 유저 이름이다. 

하지만 스크립트를 실행하기 전에 보안 서명을 하는 절차가 있다. (이게 마음에 들지 않으면 보안 옵션을 해제할 수도 있다. 몇몇 블로그에서 이것에 대해서 말하지만 별로 좋은 생각은 아닌 듯 하다.) 이 링크는 각자가 작성한 스크립트에 서명하는 방법을 설명해 주는 괜찮은 곳이다. (기사에서 저자는 snap-in을 MMC에 추가하라고 언급했다. mmc.exe를 얻으려면 File->Add/Remove Snap-in을 클릭하라. makecert.exe를 확실히 동작시키려면, 저자가 말한 makecert.exe가 포함된 디렉터리에 위치해야 한다. 또한 변경 내용이 나오기 전에 MMC 윈도우를 리프레쉬 해야한다.) 

결론 

새로운 윈도우 파워쉘은 덩치가 크지만 거기에 압도될 필요는 없다. 내가 처음 파워쉘을 사용했을 때, 그것이 나의 인생을 이렇게 편하게 해주리라고는 상상도 못했었다. 너무 생소한 커맨드들이 즐비하고 하나 같이 타이핑 하기도 힘들게 길었다. 하지만 짧은 시간 안에 나는 커맨드와 별칭 그리고 파워쉘의 세상을 이해하는 공부를 시작했다. 마지막으로 이러한 툴을 제공해준 마이크로 소프트에 감사하며, 인생을 편안하게 해줄 파워쉘 관련 커뮤니티의 작품들을 볼 수 있을 것이라는 데 흥미를 느낀다. 파워쉘을 즐겨보자. 


======================================================================================


원문 

아래에서 퍼왔지만 위에 원문 내용을 한글로 번역 한내용과 동일하며, 예제 부분이 알아볼수 없어서 원분 을 보고 다시 재수정함. 

퍼옴

Posted by Sumin Family



100대의 서버중 정품인증이 풀린 서버가 있는지 확인해야 한다면 아래의 방법이 사용가능하다

get-ciminstance -class SoftwareLicensingProduct | Where-Object { $_.ID -eq '6d47464d-e43d-4228-b051-fddd47fd403f'  }

위는 windows 2008 server r2의 라이센스를 확인하는 코드인데 guid부분은 경험적으로 얻어낸 부분이니 관리하고자 하는 서버의 id는 별도로 확인해서 해당부분만 수정해주면 된다

문제는 get-ciminstance 자체가 무시무시하게 느리다는 점인데, 시켜놓고 다른일을 해도 될만한 상황이거나, 급하게 확인할 필요가 없다면 쓸만하다고 생각한다

Posted by Sumin Family




서버에 들어가는 프로그램은 서비스로 제작되는 것이 정석이지만

관리 편의상 gui를 가진 어플리케이션의 형태로 제작되는 경우도 많다

이런 gui를 가진 어플을 특정한 계정에 자동시작되도록 하고 특정한 계정이 서버 시작시 자동으로 로그인 되게 해놓으면 일단 자동으로 구동된다는 점에서는 서비스와 같으며 별도 서비스 모니터링 툴이 필요없으니 많이들 사용하는 기법이다

하지만 파워쉘의 리모트로 접속한이후 gui를 가진 프로그램을 실행시키면 어떨까?

분명 실행은 되지만 화면에는 아무것도 나오지 않는다

이제 해결방법을 알아보자

이 부분에 대하여 여러가지 방법을 찾아보면 psexec라는 해결방법이 제일 먼저 나온다
하지만 프로그램을 별도로 받아야하며 해당프로그램으로 windows 2008 server r2에서 실험결과 정상적으로 gui가 나타나지 않았다

유일한 해결방법은 스케쥴러를 이용하는 방법이다

스케쥴러의 경우 특정한 사용자가 로그인 했을때 그 사용자에게 프로그램을 지정해서 실행시키는것이 가능한데

pssession으로 들어가서 스케쥴을 생성시킨이후 스케쥴을 실행, 삭제 하는 방법이다

좀 복잡한 방법이긴 하지만 테스트해보니 잘된다



schtasks.exe /create /ru "user1"  /sc onstart /tn remotest /tr "notepad.exe"
schtasks.exe /Run /I /TN "remotest"
schtasks.exe /Delete /TN "remotest" 

Posted by Sumin Family






[변수]

파워쉘의 기본 변수는 아래와 같습니다

$변수명

$i = 1

$i.GetType()



IsPublic IsSerial Name                                     BaseType                                                   
-------- -------- ----                                     --------                                                   
True     True     Int32                                    System.ValueType                                           



우왕 굿?


$i = 'kkk'

$i.GetType()


IsPublic IsSerial Name                                     BaseType                                                   
-------- -------- ----                                     --------                                                   
True     True     String                                   System.Object         

우왕 굿?

$i | Get-Member


Name             MemberType            Definition                                                                     
----             ----------            ----------                                                                     
Clone            Method                System.Object Clone(), System.Object ICloneable.Clone()                       
CompareTo        Method                int CompareTo(System.Object value), int CompareTo(string strB), int IComparab...
Contains         Method                bool Contains(string value)               

....

Length           Property              int Length {get;} 


엄청 많은 string의 속성들


 $i.Substring(1,2)

'kk'

헉... 굿

그냥 c# 스크립트라는 이름이 더 잘 어울릴듯...

이제 좀더 복잡한 배열의 단계로 넘어갑시다

$i = 1,2,3

$i.GetType()


IsPublic IsSerial Name                                     BaseType                                                   
-------- -------- ----                                     --------                                                   
True     True     Object[]                                 System.Array   


그렇습니다, c#에서 겁내 복잡하던 문법이 스크립트의 세계에서는 겁나 단순합니다

심지어 이런것도

$i = 1,'kakao'

좀더 적확하게 위 문장을 표현하면

$i = @(1,'kakao')

두가지는 동일합니다

이제 이런걸 해봅시다

$i = 1,2,@('사과','바나나')

$i[2][0]

>사과

zero-base로 시작되는군요

$i = 3,1,2
$i | Sort-Object

>1
>2
>3

그냥 해본 Sort-Object

$한글변수 = 1

$한글변수

> 1

한글 변수도 매우 잘되는군요

[System.Convert]::ToInt32('32')

> 32

변수와는 상관없지만 뜬금없는 .NETFRAMEWORK 사용

다음편에 해쉬를.... 살펴보겠다능...

Posted by Sumin Family


커맨드라인과 파워셀의 출력 차이점


커멘드라인과 파워쉘은 언뜻 살펴보기에는 동일한 방식으로 동작하는 것 처럼 보이지만 실제로는 입출력 대상에 큰 차이점이 있다, 먼저 이부분을 살펴보자

커멘드라인의 출력


커맨드라인은 에러와 기본출력 두가지를 가지고 있다, 그냥 단순하게 생각해서 문자열을 출력한다고 생각하면된다

dir > result.txt => 디렉토리 목록을 조회하여 result.txt로 저장
copy result.txt con => result.txt를 con로 카피
dir | more => 디렉토리 목록을 출력하는데 페이지 단위로 나누어서 출력한다
copy con test.txt => 콘솔로 입력받은 내용을 text.txt로 저장한다

위 예제에서 보이는것 처럼 모든 입출력은 문자열로 출력, 입력된다

파워쉘의 출력


ls 즉 get-childitem의 alias를 실행 해보면 보기에는 dir과 같은 내용이 출력되는 것 같지만

실제로는 get-childitem으로 얻어진 객체(.NETFRAMEWORK상의 객체) 리스트가 만들어지고 각 객체들의 프로퍼티중 Console로 출력되도록 설정된 프로퍼티가 출력되는 것이다

즉 cmd의 dir은 화면에 보여지는 정보가 전부이며 그 형식은 문자열이다
하지만 파워쉘은 눈에 보이는 출력이 전부가 아니라 각 객체의 프로퍼티중 보여지도록 설정된 부분만 보여지는 것이다

객체의 타입 살펴보기



사실 출력만 객체가 아니라 대부분 모든것이 객체이며 그 형식과 멤버를 가지고 있다


PS C:\Users\dirtyvictory> "test".gettype()
IsPublic IsSerial Name                                     BaseType                                           

-------- -------- ----                                     --------                                           
True     True     String                                   System.Object                                     



PS C:\Users\dirtyvictory> (get-item .\Desktop).gettype()
IsPublic IsSerial Name                                     BaseType                                           

-------- -------- ----                                     --------                                           
True     True     DirectoryInfo                            System.IO.FileSystemInfo                            

모든게 객체라니..

눈에 보이지 않는 모든 속성을 살펴보기


$item = get-item test.txt
get-member -inputobject $item

위 형식으로 특정파일을 get-item 으로 얻어온 객체를 $item이란 변수에 저장한 이후
get-member -inputobject로 출력해보면 실제로 눈에 보이는것 이외에 모든 멤버들을 볼 수 있다


PS C:\temp> Get-Member -InputObject $item


   TypeName: System.IO.FileInfo
Name                      MemberType     Definition                                                                                           
 

----                      ----------     ----------                                                                                            Mode                      CodeProperty   System.String Mode{get=Mode;}                                                                         AppendText                Method         System.IO.StreamWriter AppendText()                                                                 
 

CopyTo                    Method         System.IO.FileInfo CopyTo(string destFileName), System.IO.FileInfo CopyTo(string destFileName, bool...Create                    Method         System.IO.FileStream Create()                                                                         CreateObjRef              Method         System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)                                       CreateText                Method         System.IO.StreamWriter CreateText()                                                                   Decrypt                   Method         System.Void Decrypt()                                                                                 Delete                    Method         System.Void Delete()                                                                                 
 

Encrypt                   Method         System.Void Encrypt()                                                                                 Equals                    Method         bool Equals(System.Object obj)                                                                       
 

GetAccessControl          Method         System.Security.AccessControl.FileSecurity GetAccessControl(), System.Security.AccessControl.FileSe...GetHashCode               Method         int GetHashCode()                                                                                   
 

GetLifetimeService        Method         System.Object GetLifetimeService()                                                                   
 

GetObjectData             Method         System.Void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Seria...GetType                   Method         type GetType()                                                                                       
 

InitializeLifetimeService Method         System.Object InitializeLifetimeService()                                                           
 

MoveTo                    Method         System.Void MoveTo(string destFileName)                                                               Open                      Method         System.IO.FileStream Open(System.IO.FileMode mode), System.IO.FileStream Open(System.IO.FileMode mo...OpenRead                  Method         System.IO.FileStream OpenRead()                                                                       OpenText                  Method         System.IO.StreamReader OpenText()                                                                   
 

OpenWrite                 Method         System.IO.FileStream OpenWrite()                                                                     
 

Refresh                   Method         System.Void Refresh()                                                                                 Replace                   Method         System.IO.FileInfo Replace(string destinationFileName, string destinationBackupFileName), System.IO...SetAccessControl          Method         System.Void SetAccessControl(System.Security.AccessControl.FileSecurity fileSecurity)                 ToString                  Method         string ToString()                                                                                   
 

PSChildName               NoteProperty   System.String PSChildName=test.txt                                                                   
 

PSDrive                   NoteProperty   System.Management.Automation.PSDriveInfo PSDrive=C                                                    PSIsContainer             NoteProperty   System.Boolean PSIsContainer=False                                                                   
 

PSParentPath              NoteProperty   System.String PSParentPath=Microsoft.PowerShell.Core\FileSystem::C:\temp                              PSPath                    NoteProperty   System.String PSPath=Microsoft.PowerShell.Core\FileSystem::C:\temp\test.txt                           PSProvider                NoteProperty   System.Management.Automation.ProviderInfo PSProvider=Microsoft.PowerShell.Core\FileSystem             Attributes                Property       System.IO.FileAttributes Attributes {get;set;}                                                       
 

CreationTime              Property       System.DateTime CreationTime {get;set;}                                                             
 

CreationTimeUtc           Property       System.DateTime CreationTimeUtc {get;set;}                                                           
 

Directory                 Property       System.IO.DirectoryInfo Directory {get;}                                                             
 

DirectoryName             Property       System.String DirectoryName {get;}                                                                   
 

Exists                    Property       System.Boolean Exists {get;}                                                                         
 

Extension                 Property       System.String Extension {get;}                                                                       
 

FullName                  Property       System.String FullName {get;}                                                                       
 

IsReadOnly                Property       System.Boolean IsReadOnly {get;set;}                                                                  LastAccessTime            Property       System.DateTime LastAccessTime {get;set;}                                                           
 

LastAccessTimeUtc         Property       System.DateTime LastAccessTimeUtc {get;set;}                                                          LastWriteTime             Property       System.DateTime LastWriteTime {get;set;}                                                              LastWriteTimeUtc          Property       System.DateTime LastWriteTimeUtc {get;set;}                                                           Length                    Property       System.Int64 Length {get;}                                                                            Name                      Property       System.String Name {get;}                                                                             BaseName                  ScriptProperty System.Object BaseName {get=if ($this.Extension.Length -gt 0){$this.Name.Remove($this.Name.Length -...VersionInfo               ScriptProperty System.Object VersionInfo {get=[System.Diagnostics.FileVersionInfo]::GetVersionInfo($this.FullName);} 



모든 리다이렉션과 출력, 입력은 객체로 이루어진다 문자열을 입력하더라도 결국 문자열은 .NETFRAMEWORK의 string객체로 바뀌어 처리된다

이후 파워쉘의 리다이렉션과 스크립트상의 문법에 대하여 알아보자


'Server Story.... > PowerShell' 카테고리의 다른 글

파워쉘로 리모트에 gui화면 실행  (0) 2013.03.29
파워쉘의 기본문법1  (0) 2013.03.29
파워쉘의 출력에 대하여  (0) 2013.03.29
스크립트 파일을 실행하기 위한 설정  (0) 2013.03.29
파워쉘 실행  (0) 2013.03.29
파워쉘 비밀번호 암호화  (0) 2013.03.29
Posted by Sumin Family


파워쉘 스크립트가 실행되지 않는다?


먼저 파워쉘 ise를 실행해보자

위쪽 편집창에 간단한 명령어 dir 을 기록한이후 ctrl-s를 눌러 파일을 저장한후

스크립트를 실행하는 핫키인 F5를 눌러보면 다음과 같은 메시지가 나오면서 스크립트가 실행되지 않는다

이 시스템에서 스크립트를 실행할 수 없으므로 C:\Users\dirtyvictory\Desktop\제목 없음1.ps1 파일을 로드할 수 없습니다. 자세한 내용은 "get-help about_signing"을 참조하십시오.
At line:0 char:0

애시당초 이해가 안되는 설정이지만 바꿀수 있으니 바꿔주자

문제는 내가 이걸 100대의 서버에 똑같이 한번은 쳐야 한다는거 뿐이니깐

Set-ExecutionPolicy Unrestricted

위와 같이 쳐주면 뭐라 뭐라 물어보는데 Y 를 눌러주자
사용자 입력을 생략하고 싶으면 

Set-ExecutionPolicy Unrestricted -force

위와 같이 -force 옵션을 넣어주면 된다, 이 옵션은 대부분 사용자 입력을 필요로 하는 명령들에서 가능한 옵션이니 알아두면 좋음

위 옵션의 의미와 내용은 일단 무시하고, 이 명령은 원격지원에서는 다시 다른설정이 필요하며 지금은 로컬에서의 실행만 가능하게 해준다는점에 주의하자

Y를 누르거나 -force를 선택해서 생기는 모든 책임은 본인에게 있음



'Server Story.... > PowerShell' 카테고리의 다른 글

파워쉘의 기본문법1  (0) 2013.03.29
파워쉘의 출력에 대하여  (0) 2013.03.29
스크립트 파일을 실행하기 위한 설정  (0) 2013.03.29
파워쉘 실행  (0) 2013.03.29
파워쉘 비밀번호 암호화  (0) 2013.03.29
파워쉘 명령어 기본  (0) 2013.03.29
Posted by Sumin Family



파워쉘의 실행

파워쉘을 배워보기에 앞서 기본적인 실행방법과 차이점을 알아보자

실행방법들


파워쉘은 명령창의 형태로 실행하는 PowerShell과

명령창형태

명령편집과 디버깅 그리고 명령창을 함께 제공하는 파워쉘 ISE이 제공된다

파워쉘 ISE
그리고 스크립트 형태의 *.ps1로 실행이 가능하다



명령창 형태의 실행

powershell을 그냥 실행시키면 cmd.exe의 실행과 동일한 형태의 명령창이 실행된다
기본적인 dir등의 명령이 실행되지만 대부분 파워쉘 명령의 alias 즉 별칭에 불과하다
파워쉘을 통한 간단한 명령실행이나 조회 설정등에 사용할 수 있다

본격적인 명령 편집과 디버깅은 파워쉘 ISE를 사용하는 편이 더 좋다

파워쉘 ISE

ISE버전은 최상단 스크립트 편집기와 가운데 출력창 그리고 하단의 명령창을 가지고 있다
명령창에서 스크립트에 필요한 명령을 시험할 수 있다

기본적인 편집기능 이외에도 디버깅 기능까지 제공하며 디버깅 및 편집환경은 VisualStudio와 동일한 핫키를 제공하니 개발자라면 불편없이 사용가능하다

윈도우에서는 기본적으로 스크립트에 대한 실행이 방지되어 있기 때문에 편집창을 통한 실행과 디버깅은 먼저 스크립트 실행에 대한 설정이 완료되어야 한다

스크립트를 통한 실행

*.ps1의 형태로 만들어진 스크립트파일을 만들어 실행하는 기능이다
기본적으로 윈도우에서의 파워쉘 스크립트는 실행권한이 없기 때문에 별도의 설정이 필요하다 그 설정은 다음번에 알아보자

특이하게도 ps1파일은 더블클릭을 했을때 실행이 기본설정이 아니다

'Server Story.... > PowerShell' 카테고리의 다른 글

파워쉘의 기본문법1  (0) 2013.03.29
파워쉘의 출력에 대하여  (0) 2013.03.29
스크립트 파일을 실행하기 위한 설정  (0) 2013.03.29
파워쉘 실행  (0) 2013.03.29
파워쉘 비밀번호 암호화  (0) 2013.03.29
파워쉘 명령어 기본  (0) 2013.03.29
Posted by Sumin Family



파워쉘에서의 비밀번호 관리

여러대의 서버를 관리할때 명령창에서 비밀번호를 입력해야할 일이 많다

예를 들어 네트워크 드라이브를 생성하는 net 명령의 경우 아래의 문법을 사용한다

* 네트워크 드라이브 생성
사용자: patch_user네트워크경로 : \\patch_server\patch비밀번호 : password대상 드라이브 : p:
net use p: password \\patch_server\patch /user:patch_user

* 네트워크 드라이브 제거
net use /y /d p: 

위와 같은경우 스크립트를 작성하게 되면 그대로 비밀번호를 노출하게 된다


해결책

사용자에게 비밀번호를 입력받고 이를 암호화 하여 파일로 저장한다
비밀번호가 필요할때는 파일에서 읽어온 암호화된 문자열을 복호화하여 사용한다
암호화된 비밀번호파일은 다른 계정이나 컴퓨터로 가져갈경우 복호화 되지 않는다

전체 소스


$password_file = 'password.dat'

if(Test-Path $password_file)
{
    $pwd = Get-Content $password_file
}
else
{
    $pwd = Read-Host -AsSecureString "비밀번호 입력" | ConvertFrom-SecureString
    $pwd | Set-Content $password_file
}

"입력된 값을 암호화된 문자열로 변경한 값" + $pwd
try
{
    $spwd = ConvertTo-SecureString $pwd
}
catch [exception]
{    
    $pwd = Read-Host -AsSecureString "저장된 패스워드가 잘못되었습니다, 새로 입력하세요" | ConvertFrom-SecureString
    $pwd | Set-Content $password_file
}
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($spwd) 
"암호화된 문자열을 다시 일반문자열로 변환"
[Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)

'Server Story.... > PowerShell' 카테고리의 다른 글

파워쉘의 기본문법1  (0) 2013.03.29
파워쉘의 출력에 대하여  (0) 2013.03.29
스크립트 파일을 실행하기 위한 설정  (0) 2013.03.29
파워쉘 실행  (0) 2013.03.29
파워쉘 비밀번호 암호화  (0) 2013.03.29
파워쉘 명령어 기본  (0) 2013.03.29
Posted by Sumin Family




[파워쉘의 명령어란?]

도스에서 내장명령어, 내부명령어는 파워쉘에서는 cmd-let이라고 불린다
한글로는 커맨드렛이라 읽으면 된다

[파워쉘의 명령어 조회]

파워쉘의 명령어 목록을 구하려면 get-command 명령을 입력한다, 그런데 이 명령어을이 하나둘도 아니고 무더기로 나오는데 이게 무슨 도움이 될런지 모르겠다

[명령어의 도움말 보기]

보다 유용한 명령어 습득은 해당기능에 대한 구글링이다

구글링을 통해 명령어의 이름을 알았다면 보다 구체적인 명령어의 예제나 문법 정보가 필요할텐데
이때 사용하는 명령이 get-help 명령이다

cmd 일명 커맨드라인의 dir 에 해당하는 명령인 get-childitem의 도움말을 보려면 다음과 같이 입력한다

get-help get-childitem

옵션으로 -examples, -detail, -full이 준비되어 있으니 대부분 어렵지 않게 예제와 사용법을 알 수 있으며 모든정보가 한글로 제공되니 구글링과 함께 부지런히 살펴보자

[파워쉘 명령어의기본규칙]

아까입력한 get-command 명령과 get-help명령어의 구성을 보면 알겠지만 파워쉘의 명령어는 규칙이 있다

동사-명사

의 형태로 구성되어 있다는 점이다

서비스를 제어하는 명령을 예로들면

get-service : 서비스 목록을 구하는 명령어

start-service : 지정한 서비스를 시작시키는 명령어

stop-service : 지정한 서비스를 중지 시키는 명령어

위 처럼 항상 동일한 규칙이 있으며 get- 입력이후는 tab키를 눌러서 명령을 쉽게 고를수도 있다

tab키는 -로 시작하는 옵션에서도 사용가능한점이 cmd와는 다른점으로 치기힘든 긴 옵션을 쉽게 선택할 수 있게 해준다

[파워쉘의 옵션]

파워쉘에서는 전통적인 Microsoft 옵션형식인 / 을 사용하지 않고 유닉스 계열의 - 기호를 사용한다
옵션도 Tab키를 사용가능한점이 특징

[파워쉘에서의 경로]

파워셀은 파워쉘 명령어 이외 외부 프로그램을 실행할때 유닉스와 마찬가지로 현재경로를 기본 실행경로로 사용하지 않는다, 따라서 현재 경로의 프로그램을 실행할때는 ./를 사용해야한다

그리고 유닉스와 반대 기호를 사용했던 디렉토리 구분기호 \는 /와 \를 혼용할 수 있도록 변경되었다



http://powershellabc.blogspot.kr/2012/12/blog-post_30.html?view=flipcard   글 참조.

'Server Story.... > PowerShell' 카테고리의 다른 글

파워쉘의 기본문법1  (0) 2013.03.29
파워쉘의 출력에 대하여  (0) 2013.03.29
스크립트 파일을 실행하기 위한 설정  (0) 2013.03.29
파워쉘 실행  (0) 2013.03.29
파워쉘 비밀번호 암호화  (0) 2013.03.29
파워쉘 명령어 기본  (0) 2013.03.29
Posted by Sumin Family


티스토리 툴바