다음을 통해 공유


8장 - PowerShell 원격

PowerShell에서는 다양한 방법으로 원격 컴퓨터에 대한 명령을 실행할 수 있습니다. 마지막 챕터에서는 CIM cmdlet을 사용하여 WMI를 원격으로 쿼리하는 방법을 알아보았습니다. PowerShell에는 기본 제공 ComputerName 매개 변수가 있는 여러 cmdlet도 포함되어 있습니다.

다음 예제 Get-Command 와 같이 ParameterName 매개 변수와 함께 사용하여 ComputerName 매개 변수가 있는 명령을 확인할 수 있습니다.

Get-Command -ParameterName ComputerName
CommandType     Name                           Version    Source
-----------     ----                           -------    ------
Cmdlet          Add-Computer                   3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Clear-EventLog                 3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Connect-PSSession              3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Enter-PSSession                3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Get-EventLog                   3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Get-HotFix                     3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Get-Process                    3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Get-PSSession                  3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Get-Service                    3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Get-WmiObject                  3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Invoke-Command                 3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Invoke-WmiMethod               3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Limit-EventLog                 3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          New-EventLog                   3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          New-PSSession                  3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Receive-Job                    3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Receive-PSSession              3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Register-WmiEvent              3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Remove-Computer                3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Remove-EventLog                3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Remove-PSSession               3.0.0.0    Microsoft.PowerShell.Core
Cmdlet          Remove-WmiObject               3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Rename-Computer                3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Restart-Computer               3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Send-MailMessage               3.1.0.0    Microsoft.PowerShell.Utility
Cmdlet          Set-Service                    3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Set-WmiInstance                3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Show-EventLog                  3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Stop-Computer                  3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Test-Connection                3.1.0.0    Microsoft.PowerShell.Management
Cmdlet          Write-EventLog                 3.1.0.0    Microsoft.PowerShell.Management

ComputerName 매개 변수와 Get-Hotfix 같은 Get-Process 명령 이는 Microsoft가 원격 컴퓨터에 대해 명령을 실행하기 위해 향하고 있는 장기적인 방향이 아닙니다. ComputerName 매개 변수가 있는 명령을 찾더라도 대체 자격 증명을 지정해야 하며 자격 증명 매개 변수가 없을 수 있습니다. 그리고 승격된 계정에서 PowerShell을 실행하면 사용자와 원격 컴퓨터 사이의 방화벽이 요청을 차단할 수 있습니다.

이 챕터에 설명된 PowerShell 원격 명령을 사용하려면 원격 컴퓨터에서 PowerShell 원격을 사용하도록 설정해야 합니다. cmdlet을 Enable-PSRemoting 사용하여 PowerShell 원격을 사용하도록 설정합니다.

Enable-PSRemoting
WinRM has been updated to receive requests.
WinRM service type changed successfully.
WinRM service started.

WinRM has been updated for remote management.
WinRM firewall exception enabled.

일대일 원격

원격 세션이 대화형이 되도록 하려면 일대일 원격이 원하는 것입니다. 이 유형의 원격은 cmdlet을 Enter-PSSession 통해 제공됩니다.

마지막 챕터에서 do기본 관리자 자격 증명을 이름이 지정된 $Cred변수에 저장했습니다. 아직 수행하지 않은 경우 계속 진행하여 할 일기본 관리자 자격 증명을 변수에 $Cred 저장합니다.

이렇게 하면 자격 증명을 한 번만 입력하면 현재 PowerShell 세션이 비활성화될 때까지 명령별로 계속 사용할 수 있습니다.

$Cred = Get-Credential

dc01이라는 do기본 컨트롤러에 대한 일대일 PowerShell 원격 세션을 만듭니다.

Enter-PSSession -ComputerName dc01 -Credential $Cred
[dc01]: PS C:\Users\Administrator\Documents>

앞의 예제에서는 PowerShell 프롬프트 앞에 [dc01]이 옵니다. dc01이라는 원격 컴퓨터에 대한 대화형 PowerShell 세션에 있다는 뜻입니다. 실행하는 모든 명령은 로컬 컴퓨터가 아닌 dc01에서 실행됩니다. 또한 로컬 컴퓨터가 아닌 원격 컴퓨터에 있는 PowerShell 명령에만 액세스할 수 있다는 점을 명심해야 합니다. 즉, 컴퓨터에 추가 모듈을 설치한 경우 원격 컴퓨터에서 액세스할 수 없습니다.

일대일 대화형 PowerShell 원격 세션을 통해 원격 컴퓨터에 연결된 경우 원격 컴퓨터에 효과적으로 앉아 있는 것입니다. 개체는 이 책 전체에서 다루는 것과 같은 일반 개체입니다.

[dc01]:  Get-Process | Get-Member
   TypeName: System.Diagnostics.Process

Name                       MemberType     Definition
----                       ----------     ----------
Handles                    AliasProperty  Handles = Handlecount
Name                       AliasProperty  Name = ProcessName
NPM                        AliasProperty  NPM = NonpagedSystemMemorySize64
PM                         AliasProperty  PM = PagedMemorySize64
SI                         AliasProperty  SI = SessionId
VM                         AliasProperty  VM = VirtualMemorySize64
WS                         AliasProperty  WS = WorkingSet64
Disposed                   Event          System.EventHandler Disposed(System.Object, ...
ErrorDataReceived          Event          System.Diagnostics.DataReceivedEventHandler ...
Exited                     Event          System.EventHandler Exited(System.Object, Sy...
OutputDataReceived         Event          System.Diagnostics.DataReceivedEventHandler ...
BeginErrorReadLine         Method         void BeginErrorReadLine()
BeginOutputReadLine        Method         void BeginOutputReadLine()
CancelErrorRead            Method         void CancelErrorRead()
CancelOutputRead           Method         void CancelOutputRead()
Close                      Method         void Close()
CloseMainWindow            Method         bool CloseMainWindow()
CreateObjRef               Method         System.Runtime.Remoting.ObjRef CreateObjRef(...
Dispose                    Method         void Dispose(), void IDisposable.Dispose()
Equals                     Method         bool Equals(System.Object obj)
GetHashCode                Method         int GetHashCode()
GetLifetimeService         Method         System.Object GetLifetimeService()
GetType                    Method         type GetType()
InitializeLifetimeService  Method         System.Object InitializeLifetimeService()
Kill                       Method         void Kill()
Refresh                    Method         void Refresh()
Start                      Method         bool Start()
ToString                   Method         string ToString()
WaitForExit                Method         bool WaitForExit(int milliseconds), void Wai...
WaitForInputIdle           Method         bool WaitForInputIdle(int milliseconds), boo...
__NounName                 NoteProperty   string __NounName=Process
BasePriority               Property       int BasePriority {get;}
Container                  Property       System.ComponentModel.IContainer Container {...
EnableRaisingEvents        Property       bool EnableRaisingEvents {get;set;}
ExitCode                   Property       int ExitCode {get;}
ExitTime                   Property       datetime ExitTime {get;}
Handle                     Property       System.IntPtr Handle {get;}
HandleCount                Property       int HandleCount {get;}
HasExited                  Property       bool HasExited {get;}
Id                         Property       int Id {get;}
MachineName                Property       string MachineName {get;}
MainModule                 Property       System.Diagnostics.ProcessModule MainModule ...
MainWindowHandle           Property       System.IntPtr MainWindowHandle {get;}
MainWindowTitle            Property       string MainWindowTitle {get;}
MaxWorkingSet              Property       System.IntPtr MaxWorkingSet {get;set;}
MinWorkingSet              Property       System.IntPtr MinWorkingSet {get;set;}
Modules                    Property       System.Diagnostics.ProcessModuleCollection M...
NonpagedSystemMemorySize   Property       int NonpagedSystemMemorySize {get;}
NonpagedSystemMemorySize64 Property       long NonpagedSystemMemorySize64 {get;}
PagedMemorySize            Property       int PagedMemorySize {get;}
PagedMemorySize64          Property       long PagedMemorySize64 {get;}
PagedSystemMemorySize      Property       int PagedSystemMemorySize {get;}
PagedSystemMemorySize64    Property       long PagedSystemMemorySize64 {get;}
PeakPagedMemorySize        Property       int PeakPagedMemorySize {get;}
PeakPagedMemorySize64      Property       long PeakPagedMemorySize64 {get;}
PeakVirtualMemorySize      Property       int PeakVirtualMemorySize {get;}
PeakVirtualMemorySize64    Property       long PeakVirtualMemorySize64 {get;}
PeakWorkingSet             Property       int PeakWorkingSet {get;}
PeakWorkingSet64           Property       long PeakWorkingSet64 {get;}
PriorityBoostEnabled       Property       bool PriorityBoostEnabled {get;set;}
PriorityClass              Property       System.Diagnostics.ProcessPriorityClass Prio...
PrivateMemorySize          Property       int PrivateMemorySize {get;}
PrivateMemorySize64        Property       long PrivateMemorySize64 {get;}
PrivilegedProcessorTime    Property       timespan PrivilegedProcessorTime {get;}
ProcessName                Property       string ProcessName {get;}
ProcessorAffinity          Property       System.IntPtr ProcessorAffinity {get;set;}
Responding                 Property       bool Responding {get;}
SafeHandle                 Property       Microsoft.Win32.SafeHandles.SafeProcessHandl...
SessionId                  Property       int SessionId {get;}
Site                       Property       System.ComponentModel.ISite Site {get;set;}
StandardError              Property       System.IO.StreamReader StandardError {get;}
StandardInput              Property       System.IO.StreamWriter StandardInput {get;}
StandardOutput             Property       System.IO.StreamReader StandardOutput {get;}
StartInfo                  Property       System.Diagnostics.ProcessStartInfo StartInf...
StartTime                  Property       datetime StartTime {get;}
SynchronizingObject        Property       System.ComponentModel.ISynchronizeInvoke Syn...
Threads                    Property       System.Diagnostics.ProcessThreadCollection T...
TotalProcessorTime         Property       timespan TotalProcessorTime {get;}
UserProcessorTime          Property       timespan UserProcessorTime {get;}
VirtualMemorySize          Property       int VirtualMemorySize {get;}
VirtualMemorySize64        Property       long VirtualMemorySize64 {get;}
WorkingSet                 Property       int WorkingSet {get;}
WorkingSet64               Property       long WorkingSet64 {get;}
PSConfiguration            PropertySet    PSConfiguration {Name, Id, PriorityClass, Fi...
PSResources                PropertySet    PSResources {Name, Id, Handlecount, WorkingS...
Company                    ScriptProperty System.Object Company {get=$this.Mainmodule....
CPU                        ScriptProperty System.Object CPU {get=$this.TotalProcessorT...
Description                ScriptProperty System.Object Description {get=$this.Mainmod...
FileVersion                ScriptProperty System.Object FileVersion {get=$this.Mainmod...
Path                       ScriptProperty System.Object Path {get=$this.Mainmodule.Fil...
Product                    ScriptProperty System.Object Product {get=$this.Mainmodule....
ProductVersion             ScriptProperty System.Object ProductVersion {get=$this.Main...
[dc01]:

원격 컴퓨터 관련 작업이 끝났다면 Exit-PSSession cmdlet을 이용해 일대일 원격 작업 세션을 종료하세요.

[dc01]:  Exit-PSSession

일대다 원격 작업

경우에 따라 원격 컴퓨터에서 대화형으로 작업을 수행해야 할 수 있습니다. 그러나 원격은 여러 원격 컴퓨터에서 동시에 작업을 수행할 때 훨씬 더 강력합니다. cmdlet을 Invoke-Command 사용하여 하나 이상의 원격 컴퓨터에 대해 동시에 명령을 실행합니다.

Invoke-Command -ComputerName dc01, sql02, web01 {Get-Service -Name W32time} -Credential $Cred
Status   Name        DisplayName       PSComputerName
------   ----        -----------       --------------
Running  W32time     Windows Time      web01
Start... W32time     Windows Time      dc01
Running  W32time     Windows Time      sql02

이전 예제에서는 Windows 시간 서비스의 상태 대해 세 개의 서버를 쿼리했습니다. cmdlet이 Get-Service .의 Invoke-Command스크립트 블록 내에 배치되었습니다. Get-Service는 실제로 원격 컴퓨터에서 실행되며 결과는 로컬 컴퓨터에 역직렬화한 개체로 반환됩니다.

이전 명령을 파이핑하여 Get-Member 결과가 실제로 역직렬화된 개체임을 표시합니다.

Invoke-Command -ComputerName dc01, sql02, web01 {Get-Service -Name W32time} -Credential $Cred | Get-Member
   TypeName: Deserialized.System.ServiceProcess.ServiceController

Name                MemberType   Definition
----                ----------   ----------
GetType             Method       type GetType()
ToString            Method       string ToString(), string ToString(string format, Sys...
Name                NoteProperty string Name=W32time
PSComputerName      NoteProperty string PSComputerName=sql02
PSShowComputerName  NoteProperty bool PSShowComputerName=True
RequiredServices    NoteProperty Deserialized.System.ServiceProcess.ServiceController[...
RunspaceId          NoteProperty guid RunspaceId=570313c4-ac84-4109-bf67-c6b33236af0a
CanPauseAndContinue Property     System.Boolean {get;set;}
CanShutdown         Property     System.Boolean {get;set;}
CanStop             Property     System.Boolean {get;set;}
Container           Property      {get;set;}
DependentServices   Property     Deserialized.System.ServiceProcess.ServiceController[...
DisplayName         Property     System.String {get;set;}
MachineName         Property     System.String {get;set;}
ServiceHandle       Property     System.String {get;set;}
ServiceName         Property     System.String {get;set;}
ServicesDependedOn  Property     Deserialized.System.ServiceProcess.ServiceController[...
ServiceType         Property     System.String {get;set;}
Site                Property      {get;set;}
StartType           Property     System.String {get;set;}
Status              Property     System.String {get;set;}

역직렬화된 개체에는 대부분의 메서드가 없습니다. 즉, 라이브 개체가 아닙니다. 불활성입니다. 역직렬화된 개체를 사용하여 서비스를 시작하거나 중지할 수 없습니다. 이는 명령이 원격 컴퓨터에서 실행될 때 해당 개체 상태의 스냅샷 있기 때문입니다.

그렇다고 해서 메서드 Invoke-Command 를 사용하여 서비스를 시작하거나 중지할 수 없다는 의미는 아닙니다. 즉, 원격 세션에서 메서드를 호출해야 합니다.

이 점을 증명하기 위해 Stop() 메서드를 사용하여 세 개의 원격 서버에서 Windows 시간 서비스를 중지합니다.

Invoke-Command -ComputerName dc01, sql02, web01 {(Get-Service -Name W32time).Stop()} -Credential $Cred
Invoke-Command -ComputerName dc01, sql02, web01 {Get-Service -Name W32time} -Credential $Cred
Status   Name        DisplayName       PSComputerName
------   ----        -----------       --------------
Stopped  W32time     Windows Time      web01
Stopped  W32time     Windows Time      dc01
Stopped  W32time     Windows Time      sql02

이전 챕터에서 멘션 작업을 수행하기 위해 cmdlet이 있는 경우 메서드를 사용하는 대신 사용하는 것이 좋습니다. 이전 시나리오에서는 stop 메서드 대신 cmdlet을 사용하는 Stop-Service 것이 좋습니다. 많은 사람들이 PowerShell 원격을 사용할 때 메서드를 호출할 수 없다는 오해를 받고 있기 때문에 Stop() 메서드를 사용하여 요점을 증명하기로 했습니다. 역직렬화되어 반환된 개체에서는 호출할 수 없지만 원격 세션 자체에서 호출할 수 있습니다.

PowerShell 세션

이전 섹션의 마지막 예제에서는 Invoke-Command cmdlet을 사용하여 명령 두 개를 실행했습니다. 즉, 두 개의 개별 세션을 설정하고 분할하여 두 명령을 실행해야 했습니다.

7장에서 설명하는 CIM 세션처럼, 원격 컴퓨터에 대한 PowerShell 세션에서는 명령별로 새 세션을 만들지 않고도 원격 데이터를 대상으로 여러 명령을 실행할 수 있습니다.

이 챕터 DC01, SQL02 및 WEB01에서 작업한 세 대의 컴퓨터 각각에 대한 PowerShell 세션을 만듭니다.

$Session = New-PSSession -ComputerName dc01, sql02, web01 -Credential $Cred

이제 명명된 $Session 변수를 사용하여 메서드를 사용하여 Windows 시간 서비스를 시작하고 서비스의 상태 검사.

Invoke-Command -Session $Session {(Get-Service -Name W32time).Start()}
Invoke-Command -Session $Session {Get-Service -Name W32time}
Status   Name        DisplayName       PSComputerName
------   ----        -----------       --------------
Running  W32time     Windows Time      web01
Start... W32time     Windows Time      dc01
Running  W32time     Windows Time      sql02

대체 자격 증명을 사용하여 세션을 만든 후에는 명령을 실행할 때마다 더 이상 자격 증명을 지정할 필요가 없습니다.

세션 사용을 마쳤으면 반드시 제거해야 합니다.

Get-PSSession | Remove-PSSession

요약

이 장에서는 PowerShell 원격, 하나의 원격 컴퓨터로 대화형 세션에서 명령을 실행하는 방법 및 일대다 원격을 사용하여 여러 컴퓨터에 대해 명령을 실행하는 방법에 대해 알아보았습니다. 동일한 원격 컴퓨터에 대해 여러 명령을 실행할 때 PowerShell 세션을 사용할 때의 이점도 알아보았습니다.

검토

  1. PowerShell 원격을 사용하도록 설정하려면 어떻게 해야 합니까?
  2. 원격 컴퓨터로 대화형 세션을 시작하기 위한 PowerShell 명령은 무엇인가요?
  3. 각각의 명령을 이용해 컴퓨터 이름을 지정하는 방법과 비교하면 PowerShell 원격 작업 세션 사용에는 어떤 이점이 있나요?
  4. PowerShell 원격 작업 세션을 일대일 원격 작업 세션과 함께 사용할 수 있나요?
  5. cmdlet에서 반환하는 개체 유형과 원격 컴퓨터 Invoke-Command에서 동일한 cmdlet을 실행할 때 반환되는 개체의 차이점은 무엇인가요?