Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
PowerShell offre diversi modi per eseguire comandi su computer remoti. Nell'ultimo capitolo è stato illustrato come eseguire query in remoto su WMI usando i cmdlet CIM. PowerShell include anche diversi cmdlet che includono un parametro ComputerName predefinito.
Come illustrato nell'esempio seguente, è possibile usare Get-Command
con il parametro ParameterName per identificare i cmdlet che includono un parametro 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
I comandi, Get-Process
ad esempio e Get-HotFix
includono un parametro ComputerName , ma questo approccio non è la direzione a lungo termine consigliata da Microsoft per l'esecuzione di comandi su sistemi remoti. Anche quando si trova un comando con un parametro ComputerName , spesso manca un parametro Credential , rendendo difficile specificare credenziali alternative. L'esecuzione di PowerShell da una sessione con privilegi elevati non garantisce l'esito positivo, perché un firewall di rete può bloccare la richiesta tra il sistema e il computer remoto.
Per usare i comandi di PowerShell remoting illustrati in questo capitolo, è necessario abilitare il remoting di PowerShell nel computer remoto. È possibile abilitarlo eseguendo il Enable-PSRemoting
cmdlet .
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.
Comunicazione remota uno-a-uno
Se si vuole una sessione remota interattiva, la comunicazione remota uno-a-uno è quella desiderata. Questo tipo di remoting viene fornito tramite il cmdlet Enter-PSSession
.
Archiviare le credenziali di amministratore di dominio nella $Cred
variabile . Questo approccio consente di immettere le credenziali una sola volta e di riutilizzarle in base ai singoli comandi, purché la sessione di PowerShell corrente rimanga attiva.
$Cred = Get-Credential
Avviare una sessione remota PowerShell punto-a-punto sul controller di dominio denominato "dc01".
Enter-PSSession -ComputerName dc01 -Credential $Cred
Si noti che il prompt di PowerShell è preceduto da [dc01]
. Questo prefisso indica che si è in una sessione interattiva con il computer remoto denominato dc01. Tutti i comandi eseguiti ora vengono eseguiti in dc01, non nel computer locale.
[dc01]: PS C:\Users\Administrator\Documents>
Tenere presente che è possibile accedere solo ai comandi e ai moduli di PowerShell installati nel computer remoto. Se sono stati installati altri moduli in locale, non sono disponibili nella sessione remota.
Quando si è connessi tramite una sessione remota interattiva uno-a-uno, è come se ci si trovasse direttamente nel computer remoto.
[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(Sy...
ErrorDataReceived Event System.Diagnostics.DataReceived...
Exited Event System.EventHandler Exited(Syst...
OutputDataReceived Event System.Diagnostics.DataReceived...
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 ...
Dispose Method void Dispose(), void IDisposabl...
Equals Method bool Equals(System.Object obj)
GetHashCode Method int GetHashCode()
GetLifetimeService Method System.Object GetLifetimeService()
GetType Method type GetType()
InitializeLifetimeService Method System.Object InitializeLifetim...
Kill Method void Kill()
Refresh Method void Refresh()
Start Method bool Start()
ToString Method string ToString()
WaitForExit Method bool WaitForExit(int millisecon...
WaitForInputIdle Method bool WaitForInputIdle(int milli...
__NounName NoteProperty string __NounName=Process
BasePriority Property int BasePriority {get;}
Container Property System.ComponentModel.IContaine...
EnableRaisingEvents Property bool EnableRaisingEvents {get;s...
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.ProcessModul...
MainWindowHandle Property System.IntPtr MainWindowHandle ...
MainWindowTitle Property string MainWindowTitle {get;}
MaxWorkingSet Property System.IntPtr MaxWorkingSet {ge...
MinWorkingSet Property System.IntPtr MinWorkingSet {ge...
Modules Property System.Diagnostics.ProcessModul...
NonpagedSystemMemorySize Property int NonpagedSystemMemorySize {g...
NonpagedSystemMemorySize64 Property long NonpagedSystemMemorySize64...
PagedMemorySize Property int PagedMemorySize {get;}
PagedMemorySize64 Property long PagedMemorySize64 {get;}
PagedSystemMemorySize Property int PagedSystemMemorySize {get;}
PagedSystemMemorySize64 Property long PagedSystemMemorySize64 {g...
PeakPagedMemorySize Property int PeakPagedMemorySize {get;}
PeakPagedMemorySize64 Property long PeakPagedMemorySize64 {get;}
PeakVirtualMemorySize Property int PeakVirtualMemorySize {get;}
PeakVirtualMemorySize64 Property long PeakVirtualMemorySize64 {g...
PeakWorkingSet Property int PeakWorkingSet {get;}
PeakWorkingSet64 Property long PeakWorkingSet64 {get;}
PriorityBoostEnabled Property bool PriorityBoostEnabled {get;...
PriorityClass Property System.Diagnostics.ProcessPrior...
PrivateMemorySize Property int PrivateMemorySize {get;}
PrivateMemorySize64 Property long PrivateMemorySize64 {get;}
PrivilegedProcessorTime Property timespan PrivilegedProcessorTim...
ProcessName Property string ProcessName {get;}
ProcessorAffinity Property System.IntPtr ProcessorAffinity...
Responding Property bool Responding {get;}
SafeHandle Property Microsoft.Win32.SafeHandles.Saf...
SessionId Property int SessionId {get;}
Site Property System.ComponentModel.ISite Sit...
StandardError Property System.IO.StreamReader Standard...
StandardInput Property System.IO.StreamWriter Standard...
StandardOutput Property System.IO.StreamReader Standard...
StartInfo Property System.Diagnostics.ProcessStart...
StartTime Property datetime StartTime {get;}
SynchronizingObject Property System.ComponentModel.ISynchron...
Threads Property System.Diagnostics.ProcessThrea...
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, Prio...
PSResources PropertySet PSResources {Name, Id, Handleco...
Company ScriptProperty System.Object Company {get=$thi...
CPU ScriptProperty System.Object CPU {get=$this.To...
Description ScriptProperty System.Object Description {get=...
FileVersion ScriptProperty System.Object FileVersion {get=...
Path ScriptProperty System.Object Path {get=$this.M...
Product ScriptProperty System.Object Product {get=$thi...
ProductVersion ScriptProperty System.Object ProductVersion {g...
Al termine dell'utilizzo del computer remoto, eseguire il Exit-PSSession
cmdlet per terminare la sessione remota.
[dc01]: Exit-PSSession
Comunicazione remota uno-a-molti
Anche se occasionalmente potrebbe essere necessario eseguire attività in modo interattivo in un computer remoto, la comunicazione remota di PowerShell diventa più potente quando si eseguono contemporaneamente comandi in più sistemi remoti. Usare il Invoke-Command
cmdlet per eseguire comandi in uno o più computer remoti contemporaneamente.
Nell'esempio seguente si eseguono query su tre server per lo stato del servizio Ora di Windows. Il Get-Service
cmdlet viene inserito all'interno del blocco di script di Invoke-Command
, ovvero viene eseguito in ogni computer remoto.
Invoke-Command -ComputerName dc01, sql02, web01 {
Get-Service -Name W32time
} -Credential $Cred
I risultati vengono restituiti alla sessione locale come oggetti deserializzati.
Status Name DisplayName PSComputerName
------ ---- ----------- --------------
Running W32time Windows Time web01
Start... W32time Windows Time dc01
Running W32time Windows Time sql02
Per verificare che gli oggetti restituiti siano deserializzati, inviare tramite pipe l'output a 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(strin...
Name NoteProperty string Name=W32time
PSComputerName NoteProperty string PSComputerName=dc01
PSShowComputerName NoteProperty bool PSShowComputerName=True
RequiredServices NoteProperty Deserialized.System.ServiceProcess.Servi...
RunspaceId NoteProperty guid RunspaceId=5ed06925-8037-43ef-9072-...
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.Servi...
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.Servi...
ServiceType Property System.String {get;set;}
Site Property {get;set;}
StartType Property System.String {get;set;}
Status Property System.String {get;set;}
Si noti che la maggior parte dei metodi non è presente in oggetti deserializzati. I metodi sono mancanti perché questi oggetti non sono attivi. Sono snapshot inert dello stato dell'oggetto quando si esegue il comando sul computer remoto. Ad esempio, non è possibile avviare o arrestare un servizio usando un oggetto deserializzato perché non ha più accesso ai metodi necessari.
Tuttavia, questo non significa che non è possibile usare metodi come Stop()
con Invoke-Command
. La chiave è che è necessario chiamare il metodo all'interno della sessione remota.
Arrestare il servizio Windows Time su tutti e tre i server remoti utilizzando il metodo Stop()
da remoto per dimostrare.
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
Come accennato in un capitolo precedente, se è disponibile un cmdlet per eseguire un'attività, è preferibile usarlo anziché chiamare direttamente un metodo. Ad esempio, usare il Stop-Service
cmdlet anziché il Stop()
metodo per arrestare un servizio.
Nell'esempio precedente, il Stop()
metodo viene usato per fare un punto. Alcune persone credono erroneamente che non sia possibile usare metodi con il remoting di PowerShell. Anche se è vero che non è possibile chiamare metodi su oggetti deserializzati restituiti alla sessione locale, è tuttavia possibile richiamarli all'interno della sessione remota.
Sessioni di PowerShell
Nell'esempio finale della sezione precedente sono stati eseguiti due comandi usando il Invoke-Command
cmdlet . Questo scenario ha comportato la creazione e l'interruzione di due sessioni separate. Uno per ogni comando.
Come le sessioni CIM, una sessione di PowerShell persistente consente di eseguire più comandi su un computer remoto senza il sovraccarico di creazione di una nuova sessione per ogni comando.
Creare una sessione di PowerShell in ognuno dei tre computer con cui si lavora in questo capitolo, DC01, SQL02 e WEB01.
$Session = New-PSSession -ComputerName dc01, sql02, web01 -Credential $Cred
A questo punto, usare la $Session
variabile per avviare il servizio Ora di Windows chiamando il relativo metodo e quindi verificare lo stato del servizio.
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
Dopo aver creato la sessione con credenziali alternative, non è necessario specificare di nuovo tali credenziali per ogni comando.
Assicurarsi di rimuovere le sessioni al termine dell'uso.
Get-PSSession | Remove-PSSession
Sommario
In questo capitolo sono stati illustrati i concetti fondamentali della comunicazione remota di PowerShell, tra cui l'esecuzione interattiva di comandi in un singolo computer remoto e l'esecuzione di comandi in più sistemi usando la comunicazione remota uno-a-molti. Sono stati inoltre esaminati i vantaggi dell'uso di sessioni di PowerShell persistenti quando si eseguono più comandi sullo stesso computer remoto.
Recensione
- Come si abilita la remotizzazione di PowerShell?
- Quale comando di PowerShell si usa per avviare una sessione interattiva con un computer remoto?
- Qual è il vantaggio dell'uso di una sessione remota di PowerShell anziché specificare il nome del computer con ogni comando?
- È possibile usare una sessione di PowerShell in uno scenario di comunicazione remota interattiva uno-a-uno?
- Qual è la differenza tra gli oggetti restituiti dai cmdlet eseguiti localmente e gli oggetti restituiti quando gli stessi cmdlet vengono eseguiti nei computer remoti usando
Invoke-Command
?