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 세션을 사용할 때의 이점도 알아보았습니다.
검토
- PowerShell 원격을 사용하도록 설정하려면 어떻게 해야 합니까?
- 원격 컴퓨터로 대화형 세션을 시작하기 위한 PowerShell 명령은 무엇인가요?
- 각각의 명령을 이용해 컴퓨터 이름을 지정하는 방법과 비교하면 PowerShell 원격 작업 세션 사용에는 어떤 이점이 있나요?
- PowerShell 원격 작업 세션을 일대일 원격 작업 세션과 함께 사용할 수 있나요?
- cmdlet에서 반환하는 개체 유형과 원격 컴퓨터
Invoke-Command
에서 동일한 cmdlet을 실행할 때 반환되는 개체의 차이점은 무엇인가요?
권장 참조 항목
PowerShell