์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ™œ์„ฑํ™” ํ•ด์ฃผ์„ธ์š”

p008 Scheduled Job ๋‹ค๋ฃจ๊ธฐ

 ·  โ˜• 4 min read

schtasks.exe

์œˆ๋„์šฐ์ฆˆ์—๋Š” ์˜ˆ์ „๋ถ€ํ„ฐ schtasks๋ผ๋Š” ๋ช…๋ น์–ด๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

ScheduledJob vs ScheduledTask

์ €๋Š” ScheduledJob์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ScheduledTask๋„ ๋‚˜์˜์ง€ ์•Š์€ ์ ‘๊ทผ์ž…๋‹ˆ๋‹ค. ๊ทผ๋ณธ์ ์ธ ์ฐจ์ด์ ์€

  • Scheduled Task ๋Š” ์œˆ๋„์šฐ์ฆˆ์˜ ๋ถ€๋ถ„์ด๊ณ , ๋‹ค๋ฅธ ๋ถ€๋ถ„๋“ค์„ Powershell์ด ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ Powershell๋„ ์ด๋ฅผ ์ปจํŠธ๋กค ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋ฐ˜๋ฉด Scheduled Job์€ ๊ฑฐ์˜ PowerShell ์˜ ๋ฌผ๊ฑด์ž…๋‹ˆ๋‹ค. ๋ฐ”๊ฟ” ๋งํ•˜๋ฉด scheduled job์€, Powershell ํ™˜๊ฒฝ์•ˆ์—์„œ ์‹คํ–‰๋˜๋Š”, ์‹คํ–‰ ์˜ˆ์ •๋œ PowerShell code ์ž…๋‹ˆ๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ PowerShellํ™˜๊ฒฝ์ด ์•„๋‹Œ ๊ณณ์—์„œ๋Š” Scheduled Task๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, PowerShellํ™˜๊ฒฝ์—์„œ๋Š” ์–‘์ชฝ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

GUI๋กœ ํ™•์ธํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, Task Scheduler GUI ํ”„๋กœ๊ทธ๋žจ TaskSchd.msc ์—์„œ์˜ ๊ฒฝ๋กœ๋Š” Microsoft\Windows\PowerShell\ScheduledJobs ์— ์žˆ์Šต๋‹ˆ๋‹ค.

๋””์ž์ธ์ ์ธ ์ธก๋ฉด

์‚ฌ์‹ค ์œˆ๋„์šฐ์ฆˆ์˜ ๋ฐ˜๋ณต์ž‘์—… ๋“ฑ๋ก์€, crontab๊ณผ ๋น„๊ตํ•˜๋ฉด, ์•Œ๊ธฐ ์‰ฝ๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋Š” ๋””์ž์ธ์€ ์•„๋‹Œ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๋น„ ์˜์–ด๊ถŒ์—์„œ๋Š” ๊ธˆ๋ฐฉ ์•Œ์•„๋“ค์„ ์ˆ˜ ์—†๋Š” ๋‹จ์–ด๋„ ๋“ฑ์žฅํ•ฉ๋‹ˆ๋‹ค.

๋“ฑ๋กํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์˜ต์…˜์€ ์—„์ฒญ ๋งŽ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜ ํ•˜๋‚˜ ์‚ดํŽด๋ณด๋ฉด

trigger

์–ธ์ œ ์‹คํ–‰ํ•  ์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. `AC ์ „์›์ด ๋“ค์–ด์˜ฌ ๋•Œ’์™€ ‘๋กœ๊ทธ์ธํ•  ๋•Œ’๋ฅผ ์„ ํƒํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

  • crontab์ด๋ผ๋ฉด @reboot ์™€
  • .bash_profile๋“ฑ์— ๋”ฐ๋กœ ๋‘์–ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

credential

์–ด๋–ค ๊ถŒํ•œ์œผ๋กœ ์‹คํ–‰ํ•  ์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

  • ์‹œ์Šคํ…œ๊ถŒํ•œ, MSSql, ๋˜๋Š” Domain Administrator๋“ฑ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ถŒํ•œ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์Šคํฌ๋ฆฝํŠธ๋กœ๋Š” credential object๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ์€ ์ฐธ ๊บผ๋ ค์ง€๋Š” ๋ถ€๋ถ„์ด๊ธด ํ•ฉ๋‹ˆ๋‹ค.

option

๊ณต์‹ํŽ˜์ด์ง€์—์„œ ์„ค๋ช…์„ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์—ฌ๋Ÿฌ ์˜ต์…˜์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํŽ˜์ด์ง€๋Š” ํ˜„์žฌ๊นŒ์ง€๋„ ๋ฒˆ์—ญ์ด ์•ˆ๋˜์–ด์žˆ์–ด ์˜์–ด๋กœ ๋ด์•ผํ•ฉ๋‹ˆ๋‹ค.

New-ScheduledJobOption
   [-RunElevated]
   [-HideInTaskScheduler]
   [-RestartOnIdleResume]
   [-MultipleInstancePolicy <TaskMultipleInstancePolicy>]
   [-DoNotAllowDemandStart]
   [-RequireNetwork]
   [-StopIfGoingOffIdle]
   [-WakeToRun]
   [-ContinueIfGoingOnBattery]
   [-StartIfOnBattery]
   [-IdleTimeout <TimeSpan>]
   [-IdleDuration <TimeSpan>]
   [-StartIfIdle]
   [<CommonParameters>]
  • RunElevated ๊ด€๋ฆฌ์ž ๊ทธ๋ฃน์˜ ๊ตฌ์„ฑ์›์˜ ๊ถŒํ•œ์œผ๋กœ ์˜ˆ์•ฝ๋œ ์ž‘์—…์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • HideInTaskScheduler ์‹คํ–‰์ค‘์ธ ํƒœ์Šคํฌ๋Š” ํ‘œ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์Šค์ผ€์ฅด์ค‘์ธ ํƒœ์Šคํฌ๋Š” ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์‹คํ–‰์ค‘์˜ ํƒœ์Šคํฌ๋ฅผ ์ˆจ๊ธฐ๋”๋ผ๋„ ํƒœ์Šคํฌ ์Šค์ผ€์ค„๋Ÿฌ์—์„œ ์ˆจ๊ฒจ์ง„ ํƒœ์Šคํฌ ๋ณด๊ธฐ ํ‘œ์‹œ ์˜ต์…˜์„ ํ†ตํ•ด์„œ ํ‘œ์‹œํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  • RestartOnIdleResume Idle์ด ๊บผ์ง€๋ฉด ์ค‘์ง€ํ–ˆ๋˜ ํƒœ์Šคํฌ๋ฅผ Idle์ƒํƒœ๋กœ ๋Œ์•„์˜ค๋ฉด ๋‹ค์‹œ ์‹œ์ž‘ใ„ดํ•ฉ๋‹ˆ๋‹ค.
  • MultipleInstancePolicy
  • DoNotAllowDemandStart ์ˆ˜๋™์œผ๋กœ ์‹คํ–‰์€ ๋ชปํ•˜๊ณ  Trigger์— ์˜ํ•ด์„œ๋งŒ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค.
  • RequireNetwork ๋„คํŠธ์›์ด ๋  ๋•Œ๋งŒ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
  • StopIfGoingOffIdle Idle์ƒํƒœ์—์„œ ์‹คํ–‰์„ ์‹œ์ž‘ํ–ˆ๋‹ค๊ฐ€ Idle์ƒํƒœ๋ฅผ ๋ฒ—์–ด๋‚˜๊ฒŒ๋˜๋ฉด ์‹คํ–‰์„ ์ผ๋‹จ ์ค‘์ง€ ํ•ฉ๋‹ˆ๋‹ค.
  • WakeToRun ๊ธฐ๋ณธ์ ์œผ๋กœ ์‹œ์Šคํ…œ์ด ์˜ˆ์•ฝ๋œ ์‹œ์ž‘ ์‹œ๊ฐ„์— ์ ˆ์ „ ๋ชจ๋“œ ์ƒํƒœ์— ์žˆ์œผ๋ฉด ์ž‘์—…์ด ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋ฐ, ์ ˆ์ „๋ชจ๋“œ์—์„œ ์ผ์–ด๋‚˜ ์ž‘์—…ํ•˜๋„๋ก ํ•œ๋‹ค.
  • ContinueIfGoingOnBattery ๊ธฐ๋ณธ์ ์œผ๋กœ ์˜ˆ์•ฝ๋œ ์ž‘์—…์€ ์‹œ์Šคํ…œ์˜ AC ์ „์› ์—ฐ๊ฒฐ์ด ๋Š๊ธฐ๋ฉด ์ค‘์ง€๋˜๋Š”๋ฐ, ์ด ์˜ต์…˜์œผ๋กœ ์ค‘์ง€ํ•˜์ง€ ์•Š๊ณ  ๊ณ„์† ํ•ฉ๋‹ˆ๋‹ค.
  • StartIfOnBattery ๋…ธํŠธ๋ถ์˜ ์œˆ๋„์šฐ์ฆˆ์ธ ๊ฒฝ์šฐ์—๋„ ์‹คํ–‰ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ๊ฐ’์€ False ์ž…๋‹ˆ๋‹ค.
  • IdleTimeout
  • IdleDuration
  • StartIfIdle ํŒŒ๋ผ๋ฉ”ํ„ฐ IdleDuration ์— ์„ค์ •๋œ๋งŒํผ Idle์ƒํƒœ๊ฐ€ ๊ณ„์†๋˜๋ฉด ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Register-ScheduledJob

ScheduledJob์€ ํ•œ ๋ฒˆ ๋˜๋Š” ๋ฐ˜๋ณต ์˜ˆ์•ฝ์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ์œˆ๋„์šฐ์ฆˆ PowerShell ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…์ž…๋‹ˆ๋‹ค. ScheduledJob์€ Disk์— ์ €์žฅ๋˜๊ณ  ํƒœ์Šคํฌ ์Šค์ผ€์ค„๋Ÿฌ์— ๋“ฑ๋ก๋˜๋Š”๋ฐ, ๋“ฑ๋ก๋œ Job์€ Task Scheduler์—์„œ ๊ด€๋ฆฌํ•˜๊ฑฐ๋‚˜ PowerShell์—์„œ ์Šค์ผ€์ค„๋ง๋œ ์ž‘์—… cmdlet์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ด€๋ฆฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ ์˜ˆ) ์ผ๋‹จ ๋“ฑ๋กํ•˜๊ธฐ

1
2
3
4
Register-ScheduledJob -Name "Archive-Scripts" -ScriptBlock {
  Get-ChildItem $home\*.ps1 -Recurse |
    Copy-Item -Destination "\\Server\Share\PSScriptArchive"
}

ํŠธ๋ฆฌ๊ฑฐ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ž๋™ ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Get-ScheduledTaskํ•˜์—ฌ ์ˆ˜๋™์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜๋Š” ์žˆ์Šต๋‹ˆ๋‹ค.

Trigger๋„ฃ์–ด์„œ ๋งŒ๋“ค๊ธฐ

1
2
3
4
$O = New-ScheduledJobOption -WakeToRun -StartIfIdle -MultipleInstancePolicy Queue
$T = New-JobTrigger -Weekly -At "9:00 PM" -DaysOfWeek Monday -WeeksInterval 2
$path = "\\Srv01\Scripts\UpdateVersion.ps1"
Register-ScheduledJob -Name "UpdateVersion" -FilePath $path -ScheduledJobOption $O -Trigger $T

Trigger์™€ Option ๋„ฃ์–ด์„œ ๋งŒ๋“ค๊ธฐ

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$T = @{
  Frequency="Weekly"
  At="9:00PM"
  DaysOfWeek="Monday"
  Interval=2
}
$O = @{
  WakeToRun=$true
  StartIfNotIdle=$false
  MultipleInstancePolicy="Queue"
}
Register-ScheduledJob -Trigger $T -ScheduledJobOption $O -Name UpdateVersion -FilePath "\\Srv01\Scripts\Update-Version.ps1"

์™„์„ฑ๋œ ์ฝ”๋“œ

๋‹ค์Œ์˜ ์Šคํฌ๋ฆฝํŠธ๋Š” 1์‹œ๊ฐ„๋งˆ๋‹ค ํ•œ ๋ฒˆ์”ฉ, ํ˜„์žฌ blog์˜ ํ†ต๊ณ„๋ฅผ ๊ตฌํ•ด์„œ ๋ฌด๋ฃŒ influxdb ์„œ๋น„์Šค์— ๊ธฐ๋กํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ์ž…๋‹ˆ๋‹ค.

{{ if .Inner }}
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(“token:ba7a237dbd36661c8ba79fd332cdfc77”))
{{ end }}

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

#Define the interval to repeat the job
$trigger = New-JobTrigger -Once -At 10:00PM -RepetitionInterval (New-TimeSpan -Hours 1) -RepeatIndefinitely
 
#Get user credential so that the job has access to the network
$cred = Get-Credential -UserName Administrator
 
#Set job options
$opt = New-ScheduledJobOption -RunElevated -RequireNetwork

#  -FilePath c:\scripts\Get-DCDiskSpace.ps1  
Register-ScheduledJob -Name Update-HugoInflux -Trigger $trigger -Credential $cred -MaxResultCount 10 -ScheduledJobOption $opt `
-ScriptBlock {
    $posts = get-hugopost
    $post_count = $posts.Count

    $post_count_public = ($posts | where-object {! $_.FrontMatter.draft }).Count
    $post_count_draft = ($posts | where-object { $_.FrontMatter.draft }).Count

    "public : $post_count_public"
    "draft : $post_count_draft"

    $total_line = 0
    foreach ($p in $posts) {
        $total_line += $p.Content.Split("`n").Count
    }
    $total_line
    $line_count_total = $total_line

    $total_char = 0
    foreach ($p in $posts) {
        $total_char += $p.Content.ToCharArray().Count
    }
    $total_char

    $char_count_total = $total_char

    "hugoblog,site=tkimblog post_count=$post_count,post_count_public=$post_count_public,post_count_draft=$post_count_draft,line_count_total=$line_count_total,char_count_total=$char_count_total"

    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("token:this-is-a-token-string"))
    $base64AuthInfo
    $response = Invoke-RestMethod 'https://corlysis.com:8086/write?db=crowdy' -Method POST `
        -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} `
        -Body "hugoblog,site=tkimblog post_count=$post_count,post_count_public=$post_count_public,post_count_draft=$post_count_draft,line_count_total=$line_count_total,char_count_total=$char_count_total"
}

๊ฐ์ƒ: ํ†ต๊ณ„๋ฅผ ๊ฐฑ์‹ ์ด ๋˜๋Š” ์‹œ๊ฐ„์ด ๊ฐ€๊นŒ์›Œ์ง€๋ฉด, ๋ฒˆ์ฉ ์ •์‹ ์ด ๋“ค๊ณค ํ•ฉ๋‹ˆ๋‹ค.

ScheduledJob ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ

  • ์ž‘์„ฑํ•˜๊ณ  ์žˆ๋Š” ๋ธ”๋กœ๊ทธ ์‚ฌ์ดํŠธ์˜ ํฌ์ŠคํŠธ ์ˆ˜, ๋ผ์ธ ์ˆ˜, ๊ธ€ ์ˆ˜๋“ฑ์„ ์ •๊ธฐ์ ์œผ๋กœ ํ™•์ธํ•˜๊ณ  ์‹ถ์„ ๋•Œ
  • ์ฐธ๊ณ ํ•˜๋Š” ์‚ฌ์ดํŠธ์— ์ƒˆ ๊ธ€์ด ์˜ฌ๋ผ์™€ ์žˆ๋Š” ์ง€ ์‚ดํŽด ๋ณผ ๋•Œ

๋ ˆํผ๋Ÿฐ์Šค

๊ณต์œ ํ•˜๊ธฐ

tkim
๊ธ€์“ด์ด
tkim
Software Engineer