Importare il modulo ActiveDirectory in PowerShell offline: guida completa DC → server membro

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.

Indice

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 ActiveDirectory include almeno ActiveDirectory.psd1, ActiveDirectory.psm1, DLL, sottocartelle di risorse (per esempio en-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)

PassoAzioneNote utili
IndividuareSul DC, localizza l’intera cartella del modulo (C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ActiveDirectory).Contiene manifest (ActiveDirectory.psd1), script (.psm1), DLL, risorse, help.
CopiareTrasferisci 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 permessiAccertati 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.
ImportareImport-Module ActiveDirectory (oppure specifica il percorso completo se la cartella non è nel PSModulePath).Aggiungi -Verbose per log dettagliati.
Risolvere erroriControlla 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)

  1. Apri Windows PowerShell 64 bit come amministratore.
  2. Individua la cartella del modulo: $modulePath = 'C:\Windows\System32\WindowsPowerShell\v1.0\Modules\ActiveDirectory' Test-Path $modulePath
  3. (Opzionale) Comprimi per il trasferimento: $zip = 'C:\Temp\ActiveDirectory-module.zip' Compress-Archive -Path "$modulePath\*" -DestinationPath $zip -Force
  4. Trasferisci il contenuto sul server membro usando il canale disponibile (copia offline, USB, condivisione interna).

Installazione sul server membro (destinazione)

  1. Scegli un percorso di moduli valido. I più comuni: $env:PSModulePath -split ';' Se possibile, preferisci C:\Program Files\WindowsPowerShell\Modules\ (per tutti gli utenti) e crea o estrai qui una cartella ActiveDirectory.
  2. 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
  3. (Consigliato) Sblocca i file per evitare blocchi dovuti a metadati di zona: Get-ChildItem $dest -Recurse | Unblock-File
  4. Verifica che il modulo sia visibile: Get-Module -ListAvailable ActiveDirectory | Select-Object Name, Version, Path
  5. Importa il modulo: Import-Module ActiveDirectory -Verbose
  6. 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 $session Se 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 PSModulePath in 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]::Is64BitProcess Se restituisce False, stai usando la console a 32 bit (SysWOW64) e potresti non vedere il modulo copiato sotto System32.

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.

  1. Verifica struttura: Get-ChildItem 'C:\Program Files\WindowsPowerShell\Modules\ActiveDirectory' -Recurse | Select-Object FullName
  2. Controlla che il manifest esista: Test-Path 'C:\Program Files\WindowsPowerShell\Modules\ActiveDirectory\ActiveDirectory.psd1'
  3. Abilita logging verboso: Import-Module ActiveDirectory -Verbose
  4. Traccia il caricamento dei moduli: Trace-Command -Name Module -Expression { Import-Module ActiveDirectory } -PSHost
  5. 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.IdentityModel o 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 PSModulePath come 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

  1. Elenco cmdlet disponibili: Get-Command -Module ActiveDirectory | Sort-Object Name
  2. Lettura oggetti base: Get-ADDomainController -Discover Get-ADForest | Select-Object Name, Domains
  3. 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 ActiveDirectory dal 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 disponibileGet-Module -ListAvailable ActiveDirectory
Import con log dettagliatiImport-Module ActiveDirectory -Verbose
Compatibilità PS 7Import-Module ActiveDirectory -UseWindowsPowerShell
Sblocco dei fileGet-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 caricamentoTrace-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 -UseWindowsPowerShell o un modulo compatibile.
  • Sicurezza del codice firmato – Se bloccato da Execution Policy, sblocca con Unblock-File o usa certificati di firma interni.
  • Debug rapidoImport-Module ActiveDirectory -Verbose -Debug indica 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.

Indice