Search

목적(왜하는가) : 일정기간 켜져있으면 중앙관리서버의 명령을 받아 자동으로 전원이 OFF되어야하는데 그렇지 않은 PC들에 대한 action을 취하기 위함

대상 : AD기반의 windows 운영체제(cmd batch 스크립트가 통하는 PC)

조치방법 : AD Domain Controller의 Group Policy에 task scheduler를 삽입한다. batch 파일이 주기적으로 실행되게끔

논리 : time /t를 통해 현재의 날짜를 뽑고
최초로 켜진 시간값은 여러가지 명령어 중에서도 상대적으로 출력결과가 빨리 도출되는 net statistics workstation 명령어를 활용한다.

단, 여기서 문제가 있다.
한글 OS상에서는 결과값이 한글로 출력된다.
이렇게 출력되면 영문OS 와 한글OS에서 출력 결과값을 수집하기 어려움이 있다.

그래서 다음의 명령어로 반드시 영문cmd코드페이지를 호출해서 batch를 실행하고자 한다.

chcp 437

(한글코드페이지는 949번임)

그렇게 명령을 내리면
Statistics since 2017-08-28 ?? 11:11:18
과 같은 값을 도출할 수 있게 된다.

그러면 이 PC는 2017년 8월 28일에 켜지고 지금까지 꺼지지 않았다는 뜻이 된다.

다음은 저기서 2017-08-28의 값만 추출하고 싶다. 그럴때는 batch의 for 문을 사용해야 한다.

자세한 사용법은 아래의 링크를 참조한다.

[링크]bat파일안에서 for문의 이용법 by 블르샤이닝님


우선 for /F 뒤에 delims라는 조건식으로 -와 space를 동시에 구분기호로해서
앞의 명령의 결과값을 쪼개면
statistics since 2017-08-28
까지 5개의 덩어리로 구별할 수 있다.
tokens라는 조건식으로 3부터 5까지를 변수 D,E,F에 저장하도록한다.

말로 하면 더이상 쉽게 표현할 수 없고 명령어를 보고 직관적으로 이해를 해야 한다.

for /F "tokens=3-5 delims=- " %%d in ('net statistics workstation ^| findstr since') do (set D=%%d&set E=%%e&set F=%%f)

delims뒤에 - 와 space 한칸을 넣어서 그 두개를 구분자로 사용하겠다는 의미이고
변수는 %%d부터 시작해서 차례로
tokens3-5 : 3번째에서 5번째까지의 덩어리를 취해서 순차적으로 넣겠다는 의미이다. 알파벳은 d e f 이렇게 순차적으로 올라가면서 저장되더라.

그것을 윈도우 환경변수 설정 명령어인 set에 저장되더라. 그리고 set 명령어를 쳐보면 변수가 저장됨을 알 수 있다.
명령어 in () 안에 파이프라인에 ^를 붙인 이유는 | (pipe)기호가 '작은따옴표 안에서 동작하게 하기 위함인 것 같다.
(findstr는 since만 해당하는 단어만 잡아내는 리눅스의 grep같은 명령어이다)


여기까지가 끝인 줄 알았는데 그렇게 취한 숫자에 또 다른 문제가 발생했다.

받아오는값은 2017-08-30과 같다. 그러면 08을 받아온다. 계산식에 넣을때 08은 숫자로 인식하지 않아서 배치에서 오류가 나더라.

그래서 다음의 링크에서 해결법을 찾아냈다.

[링크]Add/Remove Leading Zeroes

3번을 보면 해결방법이 나온다.
if "%B:~0,1%"=="0" SET B=%B:~1%

구문을 해석하면
B:~0,1 B라는 변수
문자열 시작위치(0 - 첫번째문자열부터)
1-첫번째까지를 취한값을 의미한다.
앞의숫자와 뒤의 숫자가 무엇을의미하는지, 예제 실습을 해보면 쉽게 알 수 있다.

<예>
%bytes:~0,-3% : byte라는 변수의 0(첫번째 문자열기준으로) -3(뒤에서3번째까지)

본론으로 돌아와서
B의 첫번째문자열 값이 0과 같으면
B=%B:~1% 1(두번째문자열을 B에 대입)
결국 08인경우 8로 만들라는 뜻이다.


다음, 현재 시간과 서버 시간의 차이를 계산하는 방법 - 정확할 필요가 없다.

간단한 알고리즘으로
8월 1일이 7월 31일보다 월은 크나 일수는 작고
2018년 1월 1일이 2017년 12월 31일보다 월수나 일수나 작지만 뒷날이 된다.

그래서 고안한것이
연도차이*12를 해서 월수를 더해주고
월수차이*30을 해서 일수에 더해주면
정확한 값은 아니지만 대충 몇일 차이인지 알 수 있을것이다.

그리고 그 차이값을 새로운 변수G에 저장하고 그 차이값이 한달(30일)이 넘어가면 action을 취하게 하면 된다.

이것을 모두 구현한 스크립트는 다음과 같다.

(echo hello 부분에 취할 action을 정해주면 된다)



:::현재날짜와 PC가 켜진 시간을 변수로 저장

FOR /F "tokens=1-3 delims=- " %%a IN ('date /t') DO (set A=%%a&set B=%%b&set C=%%c)
for /F "tokens=3-5 delims=- " %%d in ('net statistics workstation ^| findstr since') do (set D=%%d&set E=%%e&set F=%%f)

:::일 월 앞에 0이 붙어있으면 0을 제거합니다

if "%B:~0,1%"=="0" SET B=%B:~1%
if "%C:~0,1%"=="0" SET C=%C:~1%
if "%E:~0,1%"=="0" SET E=%E:~1%
if "%F:~0,1%"=="0" SET F=%F:~1%

:::연도가 바뀌면 차이만큼 일 가산

if %A% GTR %D% (
set /A ="B+(A-D)*12"
)

:::월이 바뀌면 차이만큼 일 가산

if %B% GTR %E% (
set /A C="C+(B-E)*30"
)

set /A G=%C%-%F%
echo G
if %G% GTR 30 (
echo hello
)