Ambiente chiuso, nessun Internet, ma serve usare i cmdlet AD su un server membro? In questa guida pratica spostiamo e importiamo correttamente il modulo ActiveDirectory di PowerShell dal Domain Controller, evitando l’errore “The system cannot find the file specified” e garantendo piena compatibilità anche in scenari PS 7.
Panoramica del problema
In infrastrutture isolate può capitare di dover amministrare AD da un server membro che non dispone del modulo ActiveDirectory. La tentazione più comune è copiare una o due DLL (per esempio Microsoft.ActiveDirectory.Management.dll) o l’assembly “Microsoft.ActiveDirectory.Management” privo di estensione, ma non basta: il sistema di caricamento dei moduli di PowerShell richiede l’intera struttura del modulo (manifest .psd1, script .psm1, dipendenze binarie, risorse di lingua, file guida), collocata in un percorso riconosciuto dal PSModulePath. In assenza di questi requisiti, Import-Module ActiveDirectory fallisce con “The system cannot find the file specified”.
Concetti chiave da sapere in 60 secondi
- PSModulePath: è la lista di cartelle in cui PowerShell cerca i moduli. Verificalo con
$env:PSModulePath -split ';'. Se il modulo non è in uno di questi percorsi, non verrà trovato. - Struttura del modulo: la cartella del modulo
ActiveDirectoryinclude almenoActiveDirectory.psd1,ActiveDirectory.psm1, DLL, sottocartelle di risorse (per esempioen-US), help. - Architettura della sessione: su sistemi x64 esistono PowerShell a 64 e a 32 bit. Avvia sempre la sessione x64 per evitare incongruenze con la copia del modulo da
System32. - Compatibilità PS 7: il modulo
ActiveDirectoryè nato per Windows PowerShell 5.1 (Full .NET Framework). Con PS 7+ usa-UseWindowsPowerShell, oppure un modulo compatibile specifico. - RSAT: il modulo AD fa parte degli strumenti di amministrazione remota. Offline si può installare da CAB/FoD o “prestare” dal DC copiando l’intera cartella del modulo.
Soluzione operativa (riassunto)
| Passo | Azione | Note utili |
|---|---|---|
| Individuare | Sul DC, localizza l’intera cartella del modulo (C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ActiveDirectory). | Contiene manifest (ActiveDirectory.psd1), script (.psm1), DLL, risorse, help. |
| Copiare | Trasferisci la cartella ActiveDirectory sul server di destinazione in uno dei percorsi di PSModulePath (es. C:\Program Files\WindowsPowerShell\Modules\). | La copia dell’intera cartella evita errori per file mancanti. |
| Verificare permessi | Accertati che l’account che importerà il modulo abbia almeno lettura sulla nuova cartella e sui file. | In caso di dubbi, avvia PowerShell “Esegui come amministratore”. |
| Controllare disponibilità | Esegui Get-Module -ListAvailable ActiveDirectory. | Conferma che il motore di ricerca moduli vede correttamente la cartella. |
| Importare | Import-Module ActiveDirectory (oppure specifica il percorso completo se la cartella non è nel PSModulePath). | Aggiungi -Verbose per log dettagliati. |
| Risolvere errori | Controlla struttura file, versioni .NET/PowerShell, log di errore ($Error) o Event Viewer. | Vedi la sezione “Troubleshooting avanzato”. |
Procedura dettagliata passo–passo
Preparazione sul Domain Controller (sorgente)
- Apri Windows PowerShell 64 bit come amministratore.
- Individua la cartella del modulo:
$modulePath = 'C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ActiveDirectory' Test-Path $modulePath - (Opzionale) Comprimi per il trasferimento:
$zip = 'C:\Temp\ActiveDirectory-module.zip' Compress-Archive -Path "$modulePath\*" -DestinationPath $zip -Force - Trasferisci il contenuto sul server membro usando il canale disponibile (copia offline, USB, condivisione interna).
Installazione sul server membro (destinazione)
- Scegli un percorso di moduli valido. I più comuni:
$env:PSModulePath -split ';'Se possibile, preferisciC:\Program Files\WindowsPowerShell\Modules\(per tutti gli utenti) e crea o estrai qui una cartellaActiveDirectory. - Estrai o copia la cartella
ActiveDirectory:$dest = 'C:\Program Files\WindowsPowerShell\Modules\ActiveDirectory' New-Item -ItemType Directory -Path $dest -Force | Out-Null Copia ricorsiva preservando struttura e timestamp Copy-Item -Path 'X:\Trasferimento\ActiveDirectory\*' -Destination $dest -Recurse -Force - (Consigliato) Sblocca i file per evitare blocchi dovuti a metadati di zona:
Get-ChildItem $dest -Recurse | Unblock-File - Verifica che il modulo sia visibile:
Get-Module -ListAvailable ActiveDirectory | Select-Object Name, Version, Path - Importa il modulo:
Import-Module ActiveDirectory -Verbose - Test rapido di funzionamento:
Get-Command -Module ActiveDirectory | Measure-Object Get-ADDomain | Format-List Name, DomainControllersContainer, PDCEmulator
Perché non basta copiare la sola DLL
Il modulo ActiveDirectory è un modulo composito. Il manifest (.psd1) definisce versione, dipendenze e file esportati; lo script di modulo (.psm1) inizializza alias, funzioni, caricamenti di assembly; le DLL implementano i cmdlet; le cartelle en-US/altre lingue contengono risorse e help. Copiarne una parte tronca le dipendenze e interrompe la risoluzione del modulo, causando l’errore di file mancante o di assembly non trovato.
Compatibilità: Windows PowerShell 5.1 vs PowerShell 7+
- Windows PowerShell 5.1 (Full .NET Framework): modulo supportato nativamente. Segui la procedura standard.
- PowerShell 7/7.2+ (.NET 6/7): carica il modulo tramite sessione di compatibilità Windows PowerShell:
Import-Module ActiveDirectory -UseWindowsPowerShell -Verbose in alternativa, crea la sessione compat: $session = New-PSSession -UseWindowsPowerShell Import-Module ActiveDirectory -PSSession $sessionSe la tua organizzazione utilizza il modulo ActiveDirectory.Preview o equivalenti compatibili, installali/offline e preferiscili ove documentato.
Alternative offline basate su RSAT/Features
Se hai a disposizione i pacchetti RSAT/Features on Demand in rete interna o su supporto rimovibile, puoi installare il modulo senza “prestare” la cartella dal DC.
# Windows Server (Core/Full)
Add-WindowsFeature RSAT-AD-PowerShell # oppure: Install-WindowsFeature RSAT-AD-PowerShell
Windows 10/11 OFFLINE (immagine montata)
DISM /Image:D:\Mount /Add-Capability /CapabilityName:Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0
Windows 10/11 OFFLINE (sistema in esecuzione, con sorgente FoD locale)
DISM /Online /Add-Capability /CapabilityName:Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 /Source:D:\FoD /LimitAccess
Queste opzioni sono ideali quando la conformità impone che i binari provengano da immagini firmate ufficiali.
Best practice di posizionamento e variabili d’ambiente
- Percorsi standard:
C:\Program Files\WindowsPowerShell\Modules(tutti gli utenti)~\Documents\WindowsPowerShell\Modules(solo utente corrente)C:\Windows\System32\WindowsPowerShell\v1.0\Modules(di sistema)
- Evitare percorsi “esotici”: se metti la cartella altrove, aggiungi il percorso a
PSModulePathin ambiente utente o sistema:$extra = 'D:\ModuliPersonalizzati' [Environment]::SetEnvironmentVariable( 'PSModulePath', "$($env:PSModulePath);$extra", 'Machine' ) - Sessione 64 bit: assicurati che la PowerShell usata sia x64:
[Environment]::Is64BitProcessSe restituisceFalse, stai usando la console a 32 bit (SysWOW64) e potresti non vedere il modulo copiato sottoSystem32.
Sicurezza e Execution Policy
In ambienti chiusi spesso l’esecuzione è limitata. Verifica e, se necessario, allinea le policy:
Get-ExecutionPolicy -List
Sblocca file contrassegnati come scaricati:
Get-ChildItem 'C:\Program Files\WindowsPowerShell\Modules\ActiveDirectory' -Recurse | Unblock-File
(Facoltativo e secondo policy) Esegui come amministratore per bypass temporaneo nella sessione:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope Process -Force
Troubleshooting avanzato
Errore: “The system cannot find the file specified”
Causa tipica: cartella incompleta, percorso fuori da PSModulePath, architettura errata, file bloccati.
- Verifica struttura:
Get-ChildItem 'C:\Program Files\WindowsPowerShell\Modules\ActiveDirectory' -Recurse | Select-Object FullName - Controlla che il manifest esista:
Test-Path 'C:\Program Files\WindowsPowerShell\Modules\ActiveDirectory\ActiveDirectory.psd1' - Abilita logging verboso:
Import-Module ActiveDirectory -Verbose - Traccia il caricamento dei moduli:
Trace-Command -Name Module -Expression { Import-Module ActiveDirectory } -PSHost - Esamina l’ultimo errore in dettaglio:
$err = $Error[0] $err | Format-List * -Force $err.Exception | Format-List * -Force
Errore: “Could not load file or assembly …”
Causa: dipendenza binaria non trovata o mismatch di versione .NET/architettura.
- Conferma PowerShell x64 e .NET Framework aggiornato.
- Assicurati di aver copiato tutta la cartella, incluse eventuali sottocartelle di
Microsoft.IdentityModelo risorse.
Il modulo non compare in Get-Module -ListAvailable
- Ispeziona i percorsi effettivi:
($env:PSModulePath -split ';') | ForEach-Object { $; Get-ChildItem $ -Directory -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FullName } - Se la cartella è in un percorso personalizzato, estendi
PSModulePathcome mostrato sopra.
PowerShell 7: cmdlet Get-AD* non funzionano
- Importa tramite compatibilità:
Import-Module ActiveDirectory -UseWindowsPowerShell - In scenari restrittivi, crea una funzione wrapper che apra una runspace WinPS dedicata per i cmdlet AD.
Permessi e privilegi
Per importare il modulo non servono privilegi elevati; tuttavia alcuni cmdlet AD richiedono diritti amministrativi di dominio o deleghe specifiche. Se l’importazione riesce ma i cmdlet falliscono con “Access is denied”, verifica l’account usato e l’UAC.
Verifiche funzionali dopo l’import
- Elenco cmdlet disponibili:
Get-Command -Module ActiveDirectory | Sort-Object Name - Lettura oggetti base:
Get-ADDomainController -Discover Get-ADForest | Select-Object Name, Domains - Query su utenti (in sola lettura):
Get-ADUser -Filter * -SearchBase "CN=Users,DC=contoso,DC=local" -ResultSetSize 5 | Select-Object SamAccountName, Enabled
Automazione: script “copia & verifica”
Per ridurre gli errori manuali, ecco uno script riutilizzabile che copia il modulo in modo sicuro e ne convalida la disponibilità.
param(
[Parameter(Mandatory=$true)]
[string]$SourcePath, # es: \\DC1\Share\ActiveDirectory
[string]$TargetRoot = "C:\Program Files\WindowsPowerShell\Modules",
[switch]$Force
)
$ErrorActionPreference = 'Stop'
function Test-ADModulePath {
param([string]$Path)
$required = @(
(Join-Path $Path 'ActiveDirectory.psd1'),
(Join-Path $Path 'ActiveDirectory.psm1')
)
return ($required | ForEach-Object { Test-Path $_ }) -notcontains $false
}
$target = Join-Path $TargetRoot 'ActiveDirectory'
if (Test-Path $target -and -not $Force) {
Write-Host "Il percorso $target esiste già. Usa -Force per sovrascrivere." -ForegroundColor Yellow
} else {
New-Item -ItemType Directory -Path $target -Force | Out-Null
Copy-Item -Path (Join-Path $SourcePath '*') -Destination $target -Recurse -Force
Get-ChildItem $target -Recurse | Unblock-File
}
if (-not (Test-ADModulePath -Path $target)) {
throw "Struttura modulo incompleta in $target"
}
$paths = $env:PSModulePath -split ';'
if ($paths -notcontains $TargetRoot) {
[Environment]::SetEnvironmentVariable('PSModulePath', "$($env:PSModulePath);$TargetRoot", 'Machine')
Write-Host "Aggiunto $TargetRoot a PSModulePath (Machine). Riapri PowerShell." -ForegroundColor Cyan
}
Import-Module ActiveDirectory -Verbose
Write-Host "Import riuscito. Versione:" -ForegroundColor Green
(Get-Module ActiveDirectory).Version
Aggiornamento della guida in ambienti offline
La documentazione dei cmdlet può essere importata senza Internet usando Save-Help su una macchina connessa e Update-Help -SourcePath nella rete isolata.
# Su macchina connessa:
$dest = 'D:\HelpCache\ActiveDirectory'
Save-Help -Module ActiveDirectory -DestinationPath $dest -Force
Intranet/offline:
Update-Help -Module ActiveDirectory -SourcePath \intranet\HelpCache\ActiveDirectory -Force
Checklist finale (da tenere a portata di mano)
- Hai copiato l’intera cartella
ActiveDirectorydal DC? - La cartella è in un percorso PSModulePath valido per la sessione corrente?
- La sessione è x64 e l’Execution Policy non blocca i file?
- Get-Module -ListAvailable mostra il modulo e Import-Module va a buon fine con
-Verbose? - Su PS 7, stai usando -UseWindowsPowerShell?
- Se disponibile, hai valutato l’installazione via RSAT/FoD offline per coerenza di build e firma?
FAQ operative
Posso copiare il modulo da un server che non è un DC?
Sì, purché il server abbia installato RSAT-AD-PowerShell con la stessa architettura e una versione compatibile con i tuoi sistemi.
Serve riavviare dopo la copia?
No. Solo se modifichi PSModulePath a livello di sistema potresti dover riaprire la console perché la variabile venga ricaricata.
La versione del modulo deve essere identica a quella del DC?
Non necessariamente, ma è consigliabile allineare alle build dell’ambiente per evitare differenze di comportamento dei cmdlet.
Import-Module funziona, ma i cmdlet falliscono con errori di rete.
Verifica connettività verso i DC e lo stato del servizio AD Web Services sul/i controller.
Voglio distribuire il modulo su più server.
Automatizza con lo script proposto e una share interna con controllo di versione; valuta la firma dei file e un ciclo di approvazione.
Conclusioni
La chiave del successo in ambienti offline è rispettare la struttura del modulo e collocarlo in un percorso valido. Evita copie parziali di DLL e punta a una procedura ripetibile: copia completa della cartella ActiveDirectory, sblocco dei file, verifica in Get-Module -ListAvailable, import con -Verbose. Per scenari moderni con PS 7, sfrutta la compatibilità UseWindowsPowerShell o moduli ad hoc. Quando possibile, preferisci RSAT/FoD offline per garantire integrità e tracciabilità. Seguendo i passaggi presentati, l’importazione del modulo ActiveDirectory riesce senza accesso a Internet e senza dipendere da download esterni.
Appendice: riferimenti operativi rapidi
| Attività | Comando |
|---|---|
| Elenco percorsi moduli | $env:PSModulePath -split ';' |
| Verifica modulo disponibile | Get-Module -ListAvailable ActiveDirectory |
| Import con log dettagliati | Import-Module ActiveDirectory -Verbose |
| Compatibilità PS 7 | Import-Module ActiveDirectory -UseWindowsPowerShell |
| Sblocco dei file | Get-ChildItem <PathModulo> -Recurse | Unblock-File |
| Installazione RSAT (Server) | Add-WindowsFeature RSAT-AD-PowerShell |
| Installazione RSAT (Windows 10/11 offline) | DISM /Image:D:\Mount /Add-Capability /CapabilityName:Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 |
| Traccia del caricamento | Trace-Command -Name Module -Expression { Import-Module ActiveDirectory } -PSHost |
Nota su governance e conformità
In molte organizzazioni copiare binari dal DC non è preferibile per ragioni di hardening e segregazione dei ruoli. Se la tua policy lo vieta, utilizza esclusivamente immagini FoD/RSAT firmate e archiviate nel repository software aziendale. In ogni caso, registra l’origine dei file, calcola hash (SHA-256) e conserva evidenza del processo di distribuzione per audit futuri.
Informazioni supplementari (riepilogo)
- Parte di RSAT – Il modulo AD è incluso negli strumenti RSAT. Con pacchetti CAB/Features offline:
Add-WindowsFeature RSAT-AD-PowerShell DISM /Image:D:\Mount /Add-Capability /CapabilityName:Rsat.ActiveDirectory.DS-LDS.Tools~~~~0.0.1.0 - Compatibilità PowerShell 7+ – Usa
Import-Module ActiveDirectory -UseWindowsPowerShello un modulo compatibile. - Sicurezza del codice firmato – Se bloccato da Execution Policy, sblocca con
Unblock-Fileo usa certificati di firma interni. - Debug rapido –
Import-Module ActiveDirectory -Verbose -Debugindica quale file non viene trovato.
Seguendo la procedura completa (copia dell’intero modulo + collocazione in un percorso valido del PSModulePath) l’importazione offline del modulo ActiveDirectory riesce senza richiedere connessione Internet o pacchetti esterni aggiuntivi.
