Home | Info | Research | Blog | Repos | Messages | Contact Me

 


PowerShell에서는 다른 스크립트 언어와 마찬가지로 + 연산자를 이용하여 문자열을 붙일 수 있습니다. + 연산자는 이어 붙이는 문자열이 길어 질 수록 알아보기 힘들다는 단점이 있습니다.

+ 연산자 사용

$text = "현재 시각 : " + (Get-Date)

+ 연산자를 사용하여 "현재 시각 : " 이라는 문자열과 Get-Date의 출력 결과를 붙일 수 있습니다.

"" 따옴표 안에 포함
$text = "현재 시각 : $(Get-Date)"

PowerShell에서는 "" 따옴표 안에 변수($)가 있으면 문자열이 아닌 변수 그 자체로 인식하도록 되어 있습니다. Get-Date는 $(Get-Date) 처럼 출력 결과를 변수 형태로 만들어줍니다. 물론 이것은 아래와 동일합니다.
$date = Get-Date
$text = "현재 시각 : $date"


여러 줄을 출력하고자 할 때는 어떻게 해야 할까요?

+ 연산자를 이용한 여러 줄 출력
$num1 = 10
$num2 = 20
$text = "num1 : " + $num1 + "`r`n" + "num2 : " + $num2

+ 연산자를 사용하면서 중간에 값이 있을 때에는 이처럼 변수를 + 해주고 개행 문자인 `r`n(CR LF)을 붙여줍니다.

"" 따옴표 안에 포함
$num1 = 10
$num2 = 20
$text = "num1 : $num1`r`nnum2 : $num2"

물론 변수와 `r`n도 따옴표 안에 포함할 수 있습니다.

"" 따옴표 안에 포함하면서 여려 줄을 변수에 대입
$num1 = 10
$num2 = 20
$text = @"
num1 : $num1
num2 : $num2
"
@

@" "@를 사용하면 변수에 여러 줄을 대입 할 수 있습니다. 이 때에는 `r`n으로 개행 문자를 넣어주지 않고 스크립트 상에 입력하는 그대로 개행이 이루어집니다.

연산 결과 붙이기
$num1 = 10
$num2 = 20
$text = @"
num1 : $num1
num2 : $num2
num1 + num2 = $($num1 + $num2)
"
@

앞서 Get-Date를 $(Get-Date)로 사용했던것과 마찬가지로 변수간 연산도 $($num1 + $num2) 처럼 $( ) 안에 넣어주면 됩니다.




PowerShell에는 PowerShell ISE라는 개발도구가 포함되어 있습니다. 이 개발도구를 이용하면 Visual Stuio와 같이 브레이크 포인트를 설정하고 한줄 단위로 실행해 볼 수 있습니다.

브레이크 포인트를 설정하고 싶은 줄에서 F9키를 누르면됩니다. 하지만 루프를 돌 때마다 브레이크 포인트가 걸린다면 디버깅 하기가 어려울 때가 많습니다. 이럴때에는 특정 값일 때에만 브레이크 포인트가 걸리도록 조건 브레이크 포인트를 설정하면 됩니다.

PowerShell ISE에서 gci.ps1라는 이름으로 아래 스크립트를 저장합니다.

$list = Get-ChildItem C:\Windows

foreach ($i in $list)
{
    Write-Output $i.Name
}


PowerShell ISE에도 일반 PowerShell 프롬프트와 같이 명령을 입력할 수 있는 곳이 있습니다. 이곳에 아래와 같이 입력하여 조건 브레이크 포인트를 설정합니다.

Set-PSBreakpoint -Line 5 -Script gci.ps1 -Action {if ($i.Name -match "notepad.exe") { break }}
(두줄이 아니고 한줄입니다.)

-Line 5는 스크립트 상에서 브레이크 포인트를 설정할 줄 번호입니다. $i.Name이 notepad.exe와 같으면 브레이크가 걸리도록 설정하였습니다.

이제 PowerShell ISE에서 F5를 눌러 스크립트를 실행합니다.



스크립트가 실행되면 그림과 같이 $i.name이 notepad.exe일 때 브레이크 포인트가 걸립니다.

PowerShell ISE가 아니더라도 PowerShell 프롬프트에서도 똑같이 브레이크 포인트를 설정할 수 있습니다. 이때에는 .\gci.ps1를 입력하여 스크립트를 실행하면 브레이크 포인트가 걸립니다. 그리고 브레이크 포인트가 걸리면 디버그 모드에 진입할 수 있습니다. 디버그 모드에서는 트레이스를 하려면 일일이 명령을 입력해야 하므로 PowerShell ISE를 이용하는 것이 편리합니다.




Windows Server 2008에서는 기본적으로 PowerShell 스크립트의 실행을 막아놓았습니다.

PowerShell의 스크립트 실행 설정인 Set-ExecutionPolicy RemoteSigned 같은 명령으로 설정 해준 뒤에, 직접 cmd.exe나 PowerShell 프롬프트에서 스크립트의 경로를 입력하여 실행을 하면 별 문제없이 실행이 됩니다.
 
하지만 프로그램을 이용하여 실행할 때(ShellExecuteEx 같은 프로세스 실행 API를 이용)에는 Set-ExecutionPolicy 설정을 해도 전혀 스크립트가 실행되지 않습니다.

그렇기 때문에 Windows Server 2008에서 막아놓은 스크립트 실행 설정을 풀어주어야 합니다.

시작->gpedit.msc 입력

로컬 그룹 정책 편집기가 실행됩니다.

컴퓨터 구성 -> 관리 템플릿 -> Windows 구성 요소 -> Windows PowerShell 선택 후 오른쪽 창에서 스크립트 실행 켜기(Turn On Script Execution)를 더블클릭 합니다.

1. 사용(E) 체크
2. 옵션의 실행 정책에서 로컬 스크립트 및 서명된 원격 스크립트 허용 선택

확인을 눌러 창을 닫으면 설정이 완료됩니다.






오늘은 PYRASIS.COM(피라시스닷컴)이 문을 연지 7년째 되는 날입니다.

요즘은 SNS의 시대이기도 하다 보니 블로그에는 좀 뜸해진게 사실입니다.

앞으로도 유익한 정보를 담기 위해 노력하겠습니다. 감사합니다.



PowerShell은 윈도우의 배치파일을 대체하기 위해 나왔습니다. 그렇기 때문에 기존의 배치파일 명령어도 사용할 수 있습니다. 하지만 PowerShell로 작업을 하기로 마음을 먹었다면 배치파일 스타일 대신 PowerShell 스타일로 만들어보면 좋겠죠.

echo "Hello PowerShell"
Write-Output "Hello PowerShell"
Write-Host "Hello PowerShell"

echo 정겨운 명령어입니다. 배치파일에서 문자열을 출력할 때 사용합니다. 사실 PowerShell에서 지원하는 배치파일 명령어들은 PowerShell cmdlet의 Alias(별칭)입니다. 마찬가지로 echo도 Write-Output의 별칭입니다.

Write-Output과 Write-Host의 다른 점은 Write-Host는 글자색과 배경색을 지정할 수 있다는 것입니다.

dir > $nul
Get-ChildItem | Out-Null

dir의 출력을 Null로 리다이렉션하는 명령들입니다. 배치파일에서 Null은 nul로 표시하지만 PowerShell에서는 $nul로 표시합니다. >과 같은 리다이렉션 대신 | 파이프를 이용해도 됩니다. Out-Null은 말그대로 출력 결과를 Null로 보내버립니다.

dir
Get-ChildItem

mkdir Hello
New-Item -Type Directory -Path Hello

cd C:\Windows
Set-Location C:\Windows

dir 대신에 Get-ChildItem을, mkdir 대신 New-Item을 사용해봅니다. New-Item 부분이 좀 옵션이 있어서 복잡하긴 하지만...

디렉터리 변경 명령어인 cd는 Set-Location으로 사용할 수 있습니다.




  • 2009년 말부터 지금까지 많은 일들이 있었습니다. 다니던 회사도 옮기게 되었고, 새 회사로 오고 나서도 우여곡절이 많았습니다. 다행히 프로젝트를 매우 체계적으로 진행하는 곳에서 일을 할 수 있게 되었습니다.

  • 그 무엇보다도 소프트웨어 개발팀은 팀장이 매우 중요하다는 것을 몸소 체험할 수 있었습니다.
TAG 근황



안녕하세요. 이재홍입니다.

윈도우 프로젝트 필수 유틸리티 Subversion, Trac, CruiseControl.NET에는 420페이지 "날짜를 버전으로 사용하기" 부분이 있습니다.

이제 2010년이 되었습니다. 하지만 책에 나와있는 PowerShell 스크립트 rcversion-date.ps1, tracversion-date.ps1은 2009년까지만 정상 동작하도록 되어 있습니다.

자세한 수정 방법은 윈도우 프로젝트 필수 유틸리티 추가팁 2010년 이후 PowerShell 스크립트 설정을 참고하세요.





오늘은 PYRASIS.COM(피라시스닷컴)이 문을 연지 6년째 되는 날입니다.

어쩌다 보니 5주년은 그냥 넘어가버렸습니다.

앞으로 더 나은 기술 정보를 제공할 수 있도록 노력하겠습니다. 감사합니다.



포팅 작업을 할 때 의외로 중요한 부분이 시간에 관련된 부분입니다. 별것 아닌것 같지만 특정 시간 주기로 루틴이 실행된다던가, 데이터에 시간이 포함된다면 시간 함수 처리를 잘못하면 포팅을 하고 나서도 제대로 동작이 되지 않을 때가 많습니다.

먼저 포팅에 앞서 유저 모드와 커널 모드의 시간 처리 기준에 대해 이해할 필요가 있습니다.
 - 유저 모드 : 밀리초, 100나노초
 - 커널 모드 : 100나노초

따라서 유저 모드와 커널 모드의 처리 기준이 다르다면 변환이 필요합니다. 하지만 대부분의 시간 함수는 변환 없이 사용할 수 있습니다. 이 변환기준은 대부분 동기화 객체의 대기 타임아웃 처리 정도에 사용됩니다.

typedef struct _FILETIME {
    DWORD dwLowDateTime;
    DWORD dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;

void GetSystemTimeAsFileTime(LPFILETIME lpSystemTimeAsFileTime)
{
    KeQuerySystemTime((PLARGE_INTEGER)&lpSystemTimeAsFileTime);
}

FILETIME과 같은 64비트 형태의 시간 구조체는 100나노초 단위입니다. 커널 모드에서도 64비트 형태의 LARGE_INTEGER 구조체를 사용하고 있으므로 변환 절차 없이 바로 사용할 수 있습니다.

typedef struct _SYSTEMTIME {
    WORD wYear;
    WORD wMonth;
    WORD wDayOfWeek;
    WORD wDay;
    WORD wHour;
    WORD wMinute;
    WORD wSecond;
    WORD wMilliseconds;
} SYSTEMTIME, *PSYSTEMTIME, *LPSYSTEMTIME;

void GetSystemTime(LPSYSTEMTIME lpSystemTime)
{
    LARGE_INTEGER systemTime;
    TIME_FIELDS timeFields;

    KeQuerySystemTime(&systemTime);

    RtlTimeToTimeFields(&systemTime, &timeFields);
}

SYSTEMTIME 구조체와 같이 연,월,일, 시, 분, 초, 요일을 세분화 한 것은 먼저 64비트 형식의 시간을 구한 다음 RtlTimeToTimeFields과 같은 함수로 변환해주면 됩니다.

#include <time.h>

errno_t localtime_s(struct tm * _Tm, const time_t * _Time)
{
    LARGE_INTEGER systemTime, localTime;
    TIME_FIELDS timeFields;

    KeQuerySystemTime(&systemTime);
    ExSystemTimeToLocalTime(&systemTime, &localTime);

    RtlTimeToTimeFields(&localTime, &timeFields);

    _Tm->tm_sec = timeFields.Second;
    _Tm->tm_min = timeFields.Minute;
    _Tm->tm_hour = timeFields.Hour;
    _Tm->tm_mday = timeFields.Day;
    _Tm->tm_mon = timeFields.Month;
    _Tm->tm_year = timeFields.Year;
    _Tm->tm_wday = timeFields.Weekday;

    return 0;
}

WinAPI가 아닌 CRT 함수의 경우 해당 CRT 함수의 구조체에 맞게 필드를 채워주어야 합니다. 먼저 64비트 형태의 시간을 구한 다음 ExSystemTimeToLocalTime 함수를 이용하여 로컬 타임으로 변환합니다. 그리고 RtlTimeToTimeFields으로 연,월,일... 형태로 변환한 뒤 tm 구조체에 맞게 값을 채워줍니다.



Windows Driver Kit(WDK) 7.0.0 정식 버전이 발표되었습니다.

이번 WDK 7.0.0은 Windows 7에 대응하는 버전입니다. 7.0.0 버전 부터는 Windows 2000 지원이 제외되었습니다.

그동안 Microsoft Connect를 통해서 WDK 베타 버전을 받을 수 있었지만, 이제부터 Microsoft Connect를 통하지 않고 Microsoft Download 페이지에서 직접 받을 수 있습니다.

WDK 공식 페이지 : http://www.microsoft.com/whdc/DevTools/WDK/WDKpkg.mspx

WDK 다운로드 페이지 : http://www.microsoft.com/downloads/details.aspx?FamilyID=2105564e-1a9a-4bf4-8d74-ec5b52da3d00&displaylang=en
TAG WDK, Windows 7