You are on page 1of 162

Copertina 31/01/07 17:03 Pagina 1

I LIBRIdi

UN RIFERIMENTO PRATICO PER AUTOMATIZZARE TUTTE


© 2007 Edizioni Master
Tutti i diritti riservati
LE OPERAZIONI SUL TUO SISTEMA OPERATIVO

• Automazione del sistema e del file system


60 SCRIPT

per Windows
AMMINISTRATIVI
SCRIPT
• Gestione dei servizi e delle applicazioni
• Condivisioni, connessioni e amministrazione
della rete AMMINISTRATIVI

60
per Windows

Francesco Lippo

60 SCRIPT AMMINISTRATIVI
PER WINDOWS
uante volte vi è capitato di voler

Q automatizzare questa o quell’operazione


noiosa e ripetitiva? Si certo Windows è
comodo con le sue interfacce grafiche. Ma il più
delle volte è necessario interagire con il sistema
per ottenere un risultato. Questo significa
premere bottoni, dare e ottenere feedback
continuamente e sottintende una presenza fisica
continua accanto al computer. Ci sono invece
operazioni che possono essere automatizzate
semplicemente lanciando una stringa di
comando e lasciando poi il computer ad
elaborare per conto suo. Ce ne sono altre che
possono partire in background e non richiedono
la nostra presenza. Questo libro contiene circa
sessanta esempi pratici che vi consentono di
gestire al meglio il vostro sistema e
rappresentano anche un esempio importante su
i LIbri di

cui basare eventuali successive personalizzazioni


Frontespizio 31-08-2005 17:26 Pagina 2
Frontespizio 02/02/07 14:52 Pagina 1

i libri di

60 SCRIPT
AMMINISTRATIVI per Windows

Francesco Lippo
Frontespizio 02/02/07 14:52 Pagina 2
Ind 31/01/07 17:18 Pagina 3

60 SCRIPT
AMMINISTRATIVI
Indice per Windows

INDICE
Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .5
Cercare un file su più server . . . . . . . . . . . . . . . . . . . . . . . . . . . .7
Estrarre informazioni da un log . . . . . . . . . . . . . . . . . . . . . . . . . .7
Eliminare le condivisioni nascoste . . . . . . . . . . . . . . . . . . . . . . . .9
Check drive space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .11
Controllo hotfix su più server . . . . . . . . . . . . . . . . . . . . . . . . . .14
Ricercare una determinata patch su più computer . . . . . . . . . . .16
Controllo dei file modificati . . . . . . . . . . . . . . . . . . . . . . . . . . .18
Copia di una cartella su più server . . . . . . . . . . . . . . . . . . . . . .21
Creare file di log in base alla data . . . . . . . . . . . . . . . . . . . . . . .23
Cancellare file in base alla data . . . . . . . . . . . . . . . . . . . . . . . .24
Cancellare tutte le cartelle tranne le ultime 3 . . . . . . . . . . . . . .26
Controllo del numero d’istanze di un processo . . . . . . . . . . . . .28
Monitoring degli utenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .30
Monitoring dei gruppi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .33
Monitoring della creazione/cancellazione di file . . . . . . . . . . . .35
Monitoring dei servizi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .38
Monitoring delle Server Connection . . . . . . . . . . . . . . . . . . . . .41
Monitoring delle condivisioni . . . . . . . . . . . . . . . . . . . . . . . . . .43
Elencare le condivisioni di più server . . . . . . . . . . . . . . . . . . . . .45
Salvare l’elenco delle condivisioni . . . . . . . . . . . . . . . . . . . . . . .47
Eseguire il ping verso un host con e senza WMI . . . . . . . . . . . . .50
Creare un report delle corrispondenze Server – Indirizzo IP . . . .52
Creare un report delle corrispondenze Server – MAC Address . .55
Ricercare una particolare applicazione DCOM . . . . . . . . . . . . . .58
Inviare una mail con e senza parametri . . . . . . . . . . . . . . . . . . .60
Intercettare l’evento SHUTDOWN . . . . . . . . . . . . . . . . . . . . . . .64
SQL Server Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .65
DBF Connection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .67
Impostare l’expiration date su un gruppo di utenti . . . . . . . . . .69

I libri di ioPROGRAMMO/100 script amministrativi per Windows 3


Ind 31/01/07 17:18 Pagina 4

60 SCRIPT
AMMINISTRATIVI
per Windows Indice

Verificare se un giorno equivale ad un weekend . . . . . . . . . . . .71


Elencare gli utenti di un gruppo locale specificato . . . . . . . . . . .73
Leggere una chiave del Registry sul sistema locale . . . . . . . . . .75
Leggere una chiave del Registry su un sistema remoto . . . . . . .76
Disabilitare le Administrative Shares . . . . . . . . . . . . . . . . . . . . .79
Leggere un file INI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .82
Scrivere in un file INI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .85
Ricercare e disinstallare un programma . . . . . . . . . . . . . . . . . .89
Comparare due file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .91
Ricercare una stringa all’interno di una cartella . . . . . . . . . . . . .93
Informazioni sugli attributi di un file . . . . . . . . . . . . . . . . . . . . .96
Avviare un’installazione remota . . . . . . . . . . . . . . . . . . . . . . . .99
Rinominare tutti i file di una cartella . . . . . . . . . . . . . . . . . . . .102
Rinominare/Spostare una cartella su più server . . . . . . . . . . . .104
Abilitare le NULL Session Share . . . . . . . . . . . . . . . . . . . . . . .106
Elencare le NULL Session Share . . . . . . . . . . . . . . . . . . . . . . .109
Modificare la password di un utente su più server . . . . . . . . . .111
Ottenere l’elenco dei job schedulati . . . . . . . . . . . . . . . . . . . .113
Ottenere la lista dei processi e dei relativi thread . . . . . . . . . . .115
Impostare l’IP Address da statico a dinamico . . . . . . . . . . . . . .118
Ottenere informazioni sulle variabili d’ambiente . . . . . . . . . . .120
Svuotare la cartella di Prefetch . . . . . . . . . . . . . . . . . . . . . . . .122
Avviare il controllo antivirus su di una cartella . . . . . . . . . . . . .125
Determinare gli utenti in modalità console . . . . . . . . . . . . . . .128
Eliminare una connessione di rete . . . . . . . . . . . . . . . . . . . . .131
Disabilitare una connessione di rete . . . . . . . . . . . . . . . . . . . .134
Elencare i Documenti Recenti . . . . . . . . . . . . . . . . . . . . . . . . .137
Elencare i documenti nel Cestino . . . . . . . . . . . . . . . . . . . . . .138
Controllare l’abilitazione al controllo remoto . . . . . . . . . . . . .140
Controllare l’esecuzione di uno script . . . . . . . . . . . . . . . . . . .143
Eseguire uno script direttamente su macchine remote . . . . . . .146

4 I libri di ioPROGRAMMO/100 script amministrativi per Windows


Ind 31/01/07 17:18 Pagina 5

60 SCRIPT
AMMINISTRATIVI
Introduzione per Windows

INTRODUZIONE
Chi di voi ha deciso di sfogliare il presente libro per far-
sene un’idea sommaria ed immediata dei suoi contenu-
ti, si accorgerà subito di quale sia il taglio editoriale del-
l’intero testo. Questa raccolta di script, infatti, è nata per
lo più da problematiche reali, raccolte durante il tempo
ed opportunamente modificate per renderla maggior-
mente chiara a ciascuno di voi. Lo scopo di questo testo
è fornire un supporto a chi deve risolvere problemi ana-
loghi che, spesso, sembrano essere di semplice risolu-
zione.
In questo libro non troverete sicuramente lo script per-
fetto né tantomeno si può pensare che ci sia una rispo-
sta a tutto. Mi auguro tuttavia che attraverso qualche
modifica e la fusione tra due o più listati mostrati, qual-
cuno di voi possa essere in grado di portare a termine
parte dei propri compiti.
Il linguaggio utilizzato per realizzare questi script è
esclusivamente Visual Basic Script, coadiuvato in molti
casi dal potente WMI e qualche volta da ADSI.
Prima di lasciarvi, ancora una piccola nota sulle imple-
mentazioni che troverete nel testo. Tutti gli script sono
stati provati in un ambiente di produzione e su macchi-
ne Windows (XP/2000/2003). Per alcuni di essi è neces-
saria l’esecuzione su macchine del dominio all’interno
delle quali l’utente che lancia lo script, ha diritti ammi-
nistrativi sulla macchina corrente o su quella remota
sulla quale opera lo script. In altri casi, invece, sono state
previste le istruzioni utili a fornire le credenziali corrette
per agire su server remoti.
Per tutti quegli script che prevedono l’esecuzione di
azioni su più server in sequenza, è stato previsto un file
contenente l’elenco dei nomi o degli IP di questi sistemi.

I libri di ioPROGRAMMO/100 script amministrativi per Windows 5


Ind 31/01/07 17:18 Pagina 6

60 SCRIPT
AMMINISTRATIVI
per Windows Introduzione

Il nome preimpostato in tali script è semplicemente


ElencoServer.txt (previsto nella stessa cartella ove è pre-
sente lo script avviato) ed al suo interno, su ciascuna
riga, va inserito il nome del server (o l’indirizzo IP sul
quale agire).
Buona lettura.

6 I libri di ioPROGRAMMO/100 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 7

60 SCRIPT
AMMINISTRATIVI
Cercare un file su più server per Windows

CERCARE UN FILE SU PIÙ SERVER


Questo script si occupa di ricercare un determinato file, denomi-
nato per ipotesi MyLibrary.dll, che sarebbe contenuto all’inter-
no della System Directory del sistema sul quale si sta operan-
do. Questo script, come molti altri mostrati in seguito, preleva-
no la lista delle macchine su cui operare da un file denominato
ElencoServer.txt, riposto per ipotesi all’interno della stessa direc-
tory ove si trova il file VBS. Una delle “difficoltà” che si potreb-
bero incontrare nella realizzazione di script simili a questo è
quella di determinare, per ogni sistema, l’esatto percorso di que-
sta directory (Windows potrebbe essere installato su C:\ o su
D:\, la cartella potrebbe essere Windows o WinNT, ecc.). Per de-
terminare questa informazione esistono diverse strade, tra cui quel-
la di ricorrere ad un’apposita classe WMI denominata Win32_Ope-
ratingSystem che contiene, oltre a questa informazione, molte al-
tre che potrebbero essere utili. Al termine, lo script genera un
file di log che riporta i risultati ottenuti.

Option Explicit

Dim FSO ' Oggetto File System Object


Dim SystemDir ' Memorizza la System Directory
Dim LogFile ' Puntatore al file di log
Dim LeggiFile ' Puntatore al file che contiene l'elenco
dei server
Dim ServerCorrente ' Server su cui operare
Dim Item ' Generico item della collection colItems
Dim objWMIService ' Oggetto WMI
Dim colItems ' Collection d'informazioni della classe
Win32_OperatingSystem

Const wbemFlagReturnImmediately = &H10


Const wbemFlagForwardOnly = &H20

I libri di ioPROGRAMMO/60 script amministrativi per Windows 7


007-014 02/02/07 14:56 Pagina 8

60 SCRIPT
AMMINISTRATIVI
per Windows Cercare un file su più server

' Preleva l'elenco dei server su cui effettuare il controllo


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Controlla se il file di log esiste o occorre crearlo


If (FSO.FileExists("Check.log")) Then
Set LogFile = FSO.OpenTextFile("Check.log",8)
Else
Set LogFile = FSO.CreateTextFile("Check.Log", True)
End If

' Leggi il file con l'elenco dei server e, per ognuno, cerca il file
' Per ipotesi, immaginiamo di dover cercare il file MyLibrary.DLL
' contenuto sotto %systemdir%\System32.
Do While Not LeggiFile.AtEndOfStream
' Preleva il nome del server su cui operare
ServerCorrente = LeggiFile.ReadLine

' Preleva le informazioni sulla System Directory


Set objWMIService =
GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
ServerCorrente & "\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT * FROM
Win32_OperatingSystem", "WQL", wbemFlagReturnImmediately +
wbemFlagForwardOnly)

For Each Item In colItems


SystemDir = Item.SystemDirectory
Next

' SystemDir contiene qualcosa del tipo C:\Windows\System32.


' Per costruire la stringa correttamente, sostituiamo C: con C$
SystemDir = Replace (SystemDir,":","$")

8 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 9

60 SCRIPT
AMMINISTRATIVI
Estrarre informazioni da un log per Windows

' Controlliamo ora se il file esiste


If (FSO.FileExists("\\" & ServerCorrente & "\" & SystemDir &
"\MyLibrary.DLL")) then
LogFile.WriteLine (ServerCorrente & " " & SystemDir & " SI")
Else
LogFile.WriteLine (ServerCorrente & " " & SystemDir & " NO")
End If

Loop

LogFile.Close
LeggiFile.Close

Set FSO = Nothing


Set LogFile = Nothing
Set objWMIService = Nothing
Set colItems = Nothing
Set LeggiFile = Nothing

ESTRARRE INFORMAZIONI
DA UN LOG
Questo script d’esempio è basato su un problema reale che si è
dovuto risolvere ossia quello di leggere da un file di log deter-
minate informazioni, estraendo ad ogni ricorrenza della strin-
ga Failed after 3 retries questa e la riga precedente e generan-
do di conseguenza un nuovo file di log “pulito”. Il log di parten-
za, per semplice informazione, rappresentava il log di una migra-
zione di file da un sistema all’altro. La riga Failed after 3 retries
veniva scritta all’interno del log subito dopo quella del file (com-
pleto di percorso) che si stava tentando di copiare.

Option Explicit

I libri di ioPROGRAMMO/60 script amministrativi per Windows 9


007-014 02/02/07 14:56 Pagina 10

60 SCRIPT
AMMINISTRATIVI
per Windows Estrarre informazioni da un log

Dim FSO ' Oggetto File SystemObject


Dim RigaA ' Generica riga del file
Dim RigaB ' Generica riga del file
Dim LeggiFile ' Puntatore al file da leggere
Dim LogFile ' Puntatore al file di log
Dim FileDaControllare ' Nome del file da controllare

' Nome del file da controllare. In alternativa può essere


' passato come parametro (da implementare...)
FileDaControllare = "FileDaControllare.log"

' Apriamo il file da leggere


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile(FileDaControllare)

' Controlliamo l'esistenza del file di log


If (FSO.FileExists("Check.log")) Then
Set LogFile = FSO.OpenTextFile("Check.log",8)
Else
Set LogFile = FSO.CreateTextFile("Check.Log", True)
End If

' Leggiamo l'intero file di input. Se troviamo la riga


' "Failed after 3 retries." allora riportiamo nel log
' la riga del file d'input immediatamente precedente

Do While Not LeggiFile.AtEndOfStream

RigaA = LeggiFile.ReadLine
RigaB = LeggiFile.ReadLine

If RigaB = "Failed after 3 retries." Then


LogFile.WriteLine (RigaA & vbCrlf & RigaB & vbCrlf)

10 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 11

60 SCRIPT
AMMINISTRATIVI
Eliminare le condivisioni nascoste per Windows

End If
Loop

Wscript.Echo "Ricerca tentativi falliti terminata."

LeggiFile.Close
LogFile.Close

Set FSO = Nothing


Set LeggiFile = Nothing
Set LogFile = Nothing

ELIMINARE
LE CONDIVISIONI NASCOSTE
Il problema delle condivisioni nascoste è certamente uno tra
quelli che maggiormente possono creare problemi ad un siste-
mista. Questo perché, mentre da un lato si può prevenire la con-
divisione delle cosiddette Administrative Share (che vedremo in
un altro script), dall’altro non è possibile impedire che vengano
impostate share nascoste sui sistemi diverse da quest’ultime.
Per essere sicuri di eliminare tutte le condivisioni nascoste di
un sistema (quelle per intenderci che riportano il suffisso $) pos-
siamo ricorrere a WMI, avviando una query che, servendosi del-
la classe Win32_Share, cerchi proprio questo genere di nomi di
condivisione.
Al termine dell’avvio dello script, tutte le condivisioni nascoste,
esclusa la IPC$, verranno eliminate. Al riavvio, però, si tenga
presente che, se non diversamente predisposto con alcune mo-
difiche al Registry, tutte le restanti share amministrative (AD-
MIN$, C$, ecc.) verranno comunque ripristinate.

Option Explicit

I libri di ioPROGRAMMO/60 script amministrativi per Windows 11


007-014 02/02/07 14:56 Pagina 12

60 SCRIPT
AMMINISTRATIVI
per Windows Check drive space

Dim strComputer ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim colShares ' Collection delle condivisioni
Dim objShare ' Generico item della collection colShares

strComputer = "."
' Estrai le informazioni sulle condivisioni nascoste
Set objWMIService = GetObject("winmgmts:\\" & strComputer &
"\root\cimv2")
Set colShares = objWMIService.ExecQuery ("Select Name from
Win32_Share Where Name LIKE '%$'")

' Elenca le share nascoste (togli per default la IPC$)


Wscript.Echo "Sono state rilevate " & colshares.Count -1 & "
condivisioni nascoste"

' Cancella le condivisioni nascoste


If colShares.Count-1 = 0 Then
Wscript.Echo "Non risultano condivisioni nascoste"
Else
For Each objShare In colShares
objShare.Delete
Next

Wscript.Echo "Le condivisioni sono state eliminate"


End If

Set objWMIService = Nothing


Set colShares = Nothing

CHECK DRIVE SPACE


Questo script genera un file di log che riporta le informazioni

12 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 13

60 SCRIPT
AMMINISTRATIVI
Check drive space per Windows

sullo spazio disco di ciascuna partizione rilevata. Questo gene-


re di controlli viene fatta solitamente per prevenire situazioni
di crash dovute proprio al riempimento di un drive. Per ottene-
re i dati necessari al controllo, viene sfruttato “semplicemen-
te” l’oggetto FSO (File System Object) peraltro importantissimo
e presente in tutti i restanti script del libro.

Option Explicit

Dim FSO ' Oggetto File System Object


Dim LogFile ' Puntatore al file di log
Dim Drv ' Oggetto Drive
Dim DriveType ' Tipo di drive
Dim DriveSpecification ' Drive specification
Dim DrvTotSpc ' Specifica spazio disco
Dim DrvName ' Nome del volume
Dim DriveInfo ' Messaggio con le informazioni da inviare a
video

Set FSO = CreateObject("Scripting.FileSystemObject")

' Controlla l'esistenza del file di log


If (FSO.FileExists("CheckDrive.log")) Then
Set LogFile = FSO.OpenTextFile("CheckDrive.log",8)
Else
Set LogFile = FSO.CreateTextFile("CheckDrive.Log", True)
End If

' Scansiona i drive alla ricerca della informazioni


For Each Drv In FSO.Drives
If Drv.IsReady Then
Select Case Drv.DriveType
Case 0: DriveType = "Unknown"

I libri di ioPROGRAMMO/60 script amministrativi per Windows 13


007-014 02/02/07 14:56 Pagina 14

60 SCRIPT
AMMINISTRATIVI
per Windows Check drive space

Case 1: DriveType = "Rimovibile"


Case 2: DriveType = "Fisso"
Case 3: DriveType = "Network"
Case 4: DriveType = "CD-ROM"
Case 5: DriveType = "RAM Disk"
End Select

If Drv.DriveType = 4 Then
DriveSpecification = "N/A"
Elseif Drv.FreeSpace < 1024^2 Then
DriveSpecification = FormatNumber(Drv.FreeSpace /1024,0)
& " KB"
Elseif Drv.FreeSpace < 10240^2 Then
DriveSpecification = FormatNumber(Drv.FreeSpace /(1024^2),2)
& " MB"
Else
DriveSpecification = FormatNumber(Drv.FreeSpace /(1024^2),0)
& " MB"
End If

If Drv.TotalSize < 1024^2 Then


DrvTotSpc = FormatNumber(Drv.TotalSize /1024,0) &" KB"
Elseif Drv.TotalSize < 10240^2 Then
DrvTotSpc = FormatNumber(Drv.TotalSize /(1024^2),2) &" MB"
Else
DrvTotSpc = FormatNumber(Drv.TotalSize /(1024^2),0) &" MB"
End If

If Drv.VolumeName = "" Then


DrvName = "(None)"
Else
DrvName = Drv.VolumeName
End If

14 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 15

60 SCRIPT
AMMINISTRATIVI
Controllo hotfix su più server per Windows

' Crea la stringa che andrà nel log. Volendo è possibile scartare
' una certa tipologia di drive.
DriveInfo = strDriveMsg & "Drive " & Drv.DriveLetter & " Spazio
Libero: " & DriveSpecification & vbCrlf

' Scrivi nel log le informazioni


LogFile.WriteLine DriveInfo

End If
Next

LogFile.Close

Set FSO = Nothing


Set LogFile = Nothing

CONTROLLO HOTFIX SU PIÙ


SERVER
La presenza o meno di determinate hotfix installate su un cer-
to sistema può essere determinante in certi ambienti di produ-
zione.Attraverso l’utilizzo “classico” della classe WMI Win32_Quick-
FixEngineering possiamo ottenere diverse informazioni. Questo
script legge il server su cui operare dal file ElencoServer.txt e
genera un opportuno log con le informazioni rilevate.

Option Explicit

Dim LeggiFile ' Puntatore al file contenente la lista dei server


Dim objWMIService ' Oggetto WMI
Dim colListFixes ' Collection contenente la lista delle hotfix
Dim FSO ' Oggetto File System Object
Dim LogFile ' Puntatore al file di log

I libri di ioPROGRAMMO/60 script amministrativi per Windows 15


007-014 02/02/07 14:56 Pagina 16

60 SCRIPT
AMMINISTRATIVI
per Windows Controllo hotfix su più server

Dim hotfix ' Generica hotfix


Dim ServerCorrente ' Server su cui operare

' Preleva l'elenco dei server su cui effettuare il controllo


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Controlla se il file di log esiste o occorre crearlo


Set FSO = CreateObject("Scripting.FileSystemObject")
If (FSO.FileExists("ReportHotfix.log")) Then
Set LogFile = FSO.OpenTextFile("ReportHotfix.log",8)
Else
Set LogFile = FSO.CreateTextFile("ReportHotfix.Log", True)
End If

' Crea il report con tutte le hotfix di ciascun server


Do While Not LeggiFile.AtEndOfStream

ServerCorrente = LeggiFile.ReadLine
' Ottieni la lista delle hotfix via WMI
Set objWMIService = GetObject("winmgmts:" &
"{impersonationLevel=impersonate}!\\" & ServerCorrente &
"\root\cimv2")
Set colListFixes = objWMIService.ExecQuery ("Select
Description,HotFixID,InstallDate,InstalledBy from
Win32_QuickFixEngineering")

LogFile.WriteLine "----------------------------------------------------------
--------"
LogFile.WriteLine vbTab & ServerCorrente
LogFile.WriteLine "----------------------------------------------------------
--------"

16 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 17

60 SCRIPT
AMMINISTRATIVI
Ricercare una determinata patch su più computer per Windows

' Crea il report con le hotfix trovate


For Each hotfix In colListFixes
LogFile.WriteLine "Description: " & hotfix.Description & vbTab
_
& "Hotfix ID: " & hotfix.HotFixID & vbTab _
& "Installation Date: " & hotfix.InstallDate & vbTab
_
& "Installed By: " & hotfix.InstalledBy
Next
LogFile.WriteLine "------------------------------------------------------------
------"
Loop

LogFile.Close
LeggiFile.Close

Set objWMIService = Nothing


Set colListFixes = Nothing
Set FSO = Nothing
Set LogFile = Nothing

RICERCARE UNA DETERMINATA


PATCH SU PIÙ COMPUTER
Analogamente al problema delle hotfix questo script consente
di ottenere informazioni sulle patch installate sul sistema. In
particolare, avviando lo script con l’ID della patch da ricercare,
si ottengono i dati voluti.

Option Explicit

Dim ServerCorrente ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI

I libri di ioPROGRAMMO/60 script amministrativi per Windows 17


007-014 02/02/07 14:56 Pagina 18

60 SCRIPT
AMMINISTRATIVI
per Windows Ricercare una determinata patch su più computer

Dim colListFixes ' Collection delle patch


Dim LeggiFile ' Puntatore al file che contiene l'elenco dei
server
Dim LogFile ' Puntatore al file di log
Dim FSO ' Oggetto File System Object
Dim PatchID ' ID della patch

' Controlla se viene passato allo script l'ID della patch


If Wscript.Arguments.Count = 0 Then
Wscript.Echo "E' necessario specificare l'ID della patch
da ricercare!"
Wscript.Quit
End If

PatchID = Wscript.Arguments(0)

' Preleva l'elenco dei server su cui effettuare il controllo


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Controlla se il file di log esiste o occorre crearlo


If (FSO.FileExists("CheckPatch.log")) Then
Set LogFile = FSO.OpenTextFile("CheckPatch.log",8)
Else
Set LogFile = FSO.CreateTextFile("CheckPatch.Log", True)
End If

' Leggi il file con l'elenco dei server e per ognuno controlla l'esistenza
' della patch.
LogFile.WriteLine "SERVER;PATCH"

Do While Not LeggiFile.AtEndOfStream

18 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 19

60 SCRIPT
AMMINISTRATIVI
Controllo dei file modificati per Windows

ServerCorrente = LeggiFile.ReadLine

' Ricerca la patch via WMI


Set objWMIService = GetObject("winmgmts:" &
"{impersonationLevel=impersonate}!\\" & ServerCorrente &
"\root\cimv2")
Set colListFixes = objWMIService.ExecQuery ("Select HotFixID
FROM Win32_QuickFixEngineering WHERE HotFixID = '" & PatchID &
"'")

' Crea il report con l'elenco delle macchine che hanno


' o no la patch indicata.
If colListFixes.Count > 0 Then
LogFile.WriteLine ServerCorrente & ";" & "SI"
Else
LogFile.WriteLine ServerCorrente & ";" & "NO"
End If
Loop

LeggiFile.Close
LogFile.Close

Set objWMIService = Nothing


Set colListFixes = Nothing
Set FSO = Nothing
Set LogFile = Nothing
Set LeggiFile = Nothing

CONTROLLO DEI FILE MODIFICATI


Generalmente le tante applicazioni di un ambiente di produzio-
ne generano ciascuna un proprio log con le informazioni di lo-
ro pertinenza. Talvolta, però, può accadere che per qualche ra-

I libri di ioPROGRAMMO/60 script amministrativi per Windows 19


007-014 02/02/07 14:56 Pagina 20

60 SCRIPT
AMMINISTRATIVI
per Windows Controllo dei file modificati

gione l’applicativo si fermi o non riesca a scrivere i dati nel pro-


prio log, senza che nessuno se ne accorga. Se normalmente que-
sti file sono aggiornati a cadenza periodica, possiamo predi-
sporre un controllo aggiuntivo su di essi, ad intervalli regolari di
tempo, per controllare se sono stati modificati. Il codice seguen-
te, dunque, si assicura che i file .log, contenuti in C:\LOGFolder,
siano aggiornati ogni 10 minuti. Con i commenti inseriti do-
vrebbe essere semplice modificarne il comportamento in base al-
le proprie esigenze.

Option Explicit

Dim FSO ' Oggetto File System Object


Dim FolderObject ' Oggetto Folder
Dim FilesObject ' Collection di file
Dim IntervalUnit ' Unità di misura del tempo
Dim LOGFolder ' Cartella del log

' Preleva tutti i files nella directory puntata da LOGFolder

LOGFolder = "C:\LogFiles"
Set FSO = CreateObject("Scripting.FileSystemObject")
Set FolderObject = FSO.GetFolder(LOGFolder)
Set FilesObject = FolderObject.Files

' Definisci un intervallo di controllo e l'unità di tempo (per esempio 10


min.)
INTERVAL = 10

' Crea un oggetto Dictionary per memorizzare la corrispondenza


' tra l'unità di tempo e il parametro da passare alla funzione
' DateDiff().
' I possibili valori sono:

20 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 21

60 SCRIPT
AMMINISTRATIVI
Controllo dei file modificati per Windows

' yyyy Year


'q Quarter
'm Month
'y Day of year
'd Day
'w Weekday
' ww Week of year
'h Hour
'n Minute
's Second

Set IntervalUnit = CreateObject("Scripting.Dictionary")

IntervalUnit.Add "SECONDI", "s"


IntervalUnit.Add "s", "secondi"

IntervalUnit.Add "MINUTI", "n"


IntervalUnit.Add "n","minuti"

IntervalUnit.Add "ORE", "h"


IntervalUnit.Add "h","ore"
' ...
' ----------------------------------------------------------------------
' Aggiungere righe analoghe alle precedenti se necessario...
' ----------------------------------------------------------------------
' ...
' Memorizza la propria scelta (ossia, in definitiva, 10 minuti).
' Saranno quindi controllati tutti i file non modificati negli ultimi
' 10 minuti.
IntervalExpr = IntervalUnit("MINUTI")

' Dalla collection files controlla se ci sono file .log


For Each file In FilesObject

I libri di ioPROGRAMMO/60 script amministrativi per Windows 21


007-014 02/02/07 14:56 Pagina 22

60 SCRIPT
AMMINISTRATIVI
per Windows Copia di una cartella su più server

' Se ci sono file con estensione .log


If FSO.GetExtensionName(file) = "log" Then

' Controlla la data di ultima modifica e l'ora che non sia


superiore a INTERVAL
' Il parametro “n” della DateDiff specifica che la differenza è
espressa in MINUTI

If DateDiff("n",file.datelastmodified,now)>INTERVAL then
' Scatta allarme
Msgbox "Il file " & file.name & " da " &
DateDiff(IntervalExpr,file.DateLastModified,now) & _" " &
IntervalUnit(IntervalExpr) & "!!!",, "LISTA FILE"
End if

End if
Next

' Elimina gli oggetti appena creati dalla memoria

Set FileObject = Nothing


Set FolderObject = Nothing
Set FSO = Nothing

COPIA DI UNA CARTELLA


SU PIÙ SERVER
Com’è facile intuire, questo script replica una cartella su più si-
stemi. Per semplicità la cartella di destinazione è sullo stesso
drive di quello di partenza ossia C:\. Quasi tutto quello che vie-
ne effettuato in questo listato è ad opera dell’oggetto FSO (Fi-
le System Object).

22 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 23

60 SCRIPT
AMMINISTRATIVI
Copia di una cartella su più server per Windows

Option Explicit

Dim FSO ' Oggetto File System Object


Dim SourceFolder ' Directory sorgente
Dim DestinationFolder ' Directory destinataria
Dim LeggiFile ' Puntatore al file che contiene l'elenco
dei server
Dim LogFile ' Puntatore al file di log
Dim ServerCorrente ' Computer sul quale operare

' Definisci la cartella da copiare


SourceFolder = "C:\SourceFolder"

' Leggi il file che contiene l'elenco dei server su cui copiare la cartella
Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Controlla se è necessario creare il file di log


If (FSO.fileexists("CheckCopy.log")) Then
Set LogFile = FSO.OpenTextFile("CheckCopy.log",8)
Else
Set LogFile = FSO.CreateTextFile("CheckCopy.Log", True)
End If

' Leggi il file contenente i server su cui copiare la cartella


Do While Not LeggiFile.AtEndOfStream

ServerCorrente = LeggiFile.ReadLine
DestinationFolder = "\\" & ServerCorrente & "\C$\"

On Error Resume Next


' Copia la cartella sul server corrente
FSO.CopyFolder SourceFolder,DestinationFolder,True

I libri di ioPROGRAMMO/60 script amministrativi per Windows 23


007-014 02/02/07 14:56 Pagina 24

60 SCRIPT
AMMINISTRATIVI
per Windows Creare file di log in base alla data

If Err.Number <> 0 Then


LogFile.WriteLine (ServerCorrente & " Errore! (" & Err.Description
& ")")
Err.clear
Else
LogFile.WriteLine (ServerCorrente & " OK!")
End If

Loop

LeggiFile.Close
LogFile.Close

Set FSO = Nothing


Set LeggiFile = Nothing
Set LogFile = Nothing

CREARE FILE DI LOG


IN BASE ALLA DATA
Ecco come creare un file di log che rispecchi con il nome la da-
ta corrente. Malgrado possa sembrare un’operazione semplice,
spesso qualcuno riscontra qualche difficoltà di realizzazione.

Option Explicit

Dim FSO ' Oggetto File System Object


Dim NomeFile ' Nome del file da creare
Dim LogFile ' Nome del file di log
Dim AnnoCorrente ' Anno corrente
Dim MeseCorrente ' Mese corrente
Dim GiornoCorrente ' Giorno corrente
Set FSO = CreateObject("Scripting.FileSystemObject")

24 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 25

60 SCRIPT
AMMINISTRATIVI
Cancellare file in base alla data per Windows

AnnoCorrente = Year(Date)
MeseCorrente = Month(Date)
GiornoCorrente = Day(Date)

NomeFile = GiornoCorrente & MeseCorrente & AnnoCorrente & ".log"

' Controlla se il file esiste già


If (FSO.FileExists("C:\" & NomeFile)) Then
Msgbox "Il file " & Nomefile & " esiste già!",,"Informazione"
Else
Set LogFile = FSO.CreateTextFile("C:\" & NomeFile, TRUE)
End If

LogFile.Close

Set FSO = Nothing


Set LogFile = Nothing

CANCELLARE FILE
IN BASE ALLA DATA
Questo script consente di cancellare file temporanei (per ipote-
si .TMP) che non risultino avere una data di creazione pari al
mese corrente. Solitamente questo genere di attività si compio-
no su cartelle di appoggio che temporaneamente memorizzano
dati che poi, per una qualunque ragione, non vengono cancel-
lati.

Option Explicit

Dim FSO ' Oggetto File System Object


Dim FolderObject ' Oggetto Folder
Dim FilesObject ' Collection di file

I libri di ioPROGRAMMO/60 script amministrativi per Windows 25


007-014 02/02/07 14:56 Pagina 26

60 SCRIPT
AMMINISTRATIVI
per Windows Cancellare file in base alla data

Dim SourceFolder' Cartella sorgente


Dim LogFile ' Puntatore al file di log
Dim File ' Generico file

' Preleva tutti i files nella directory C:\Temp


SourceFolder = "C:\Temp"

Set FSO = CreateObject("Scripting.FileSystemObject")


Set FolderObject = FSO.GetFolder(SourceFolder)
Set FilesObject = FolderObject.Files

' Controlliamo l'esistenza del file di log


If (FSO.FileExists("Check.log")) Then
Set LogFile = FSO.OpenTextFile("Check.log",8)
Else
Set LogFile = FSO.CreateTextFile("Check.Log", True)
End If

' Controlla se ci sono file che rispettano le caratteristiche richieste


For Each File In FilesObject

' Se i file hanno estensione TMP, il mese è diverso dal corrente e


l'anno = a quello corrente
If FSO.GetExtensionName(file)="tmp" And
(Month(File.DateCreated)<>Month(Now) Or
Year(File.DateCreated)<>Year(Now)) Then
LogFile.WriteLine "Il file " & File.Name & " è da cancellare..."
File.Delete
End if

Next

LogFile.Close

26 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 27

60 SCRIPT
AMMINISTRATIVI
Cancellare tutte le cartelle tranne le ultime 3 per Windows

' Elimina gli oggetti appena creati dalla memoria

Set FilesObject = Nothing


Set FolderObject = Nothing
Set FSO = Nothing
Set LogFile = Nothing

CANCELLARE TUTTE
LE CARTELLE TRANNE
LE ULTIME 3
Questo script è nato da un’esigenza particolare ossia elimina-
re tutte le sottocartelle contenute all’interno di una cartella prin-
cipale conservando solo quelle relative agli ultimi 3 giorni. Per
ipotesi, le sottocartelle hanno un nome del tipo 20060927 (os-
sia nel formato AAAAMMGG). Tecnicamente lo script non è mol-
to complesso da realizzare. Occorre solo tenere conto della cor-
retta gestione dei giorni precedenti a quello corrente. Con un pò
di pazienza può essere migliorato parametrizzando il numero
di giorni da “mantenere” ed inserendo un comodo file di log.

Option Explicit

Dim FSO ' Oggetto File System Object


Dim subFolder ' Oggetto sottocartella
Dim FolderName ' Nome della cartella principale
Dim Folder ' Oggetto Folder
Dim NomeSubFolder ' Nome della sottocartella
Dim DataDaConsiderare ' Data di riferimento
Dim AnnoCorrente ' Anno corrente
Dim MeseCorrente ' Mese corrente
Dim GiornoCorrente ' Giorno corrente
Dim arrFolderName(3) ' Array contenente i 3 nomi delle cartelle

I libri di ioPROGRAMMO/60 script amministrativi per Windows 27


007-014 02/02/07 14:56 Pagina 28

60 SCRIPT
AMMINISTRATIVI
per Windows Cancellare tutte le cartelle tranne le ultime 3

Dim Cont ' Contatore

FolderName = "C:\Script"

Set FSO = CreateObject("Scripting.FileSystemObject")


Set Folder = FSO.GetFolder(FolderName)

' Prendiamo in considerazione la data di oggi


DataDaConsiderare = Now

' Crea l'array che conterrà i nomi delle cartelle


For Cont = 0 To 2

AnnoCorrente = Year(DataDaConsiderare - Cont)


MeseCorrente = Month(DataDaConsiderare - Cont)
GiornoCorrente = Day(DataDaConsiderare - Cont)

' Formatta opportunamente il il mese ed il giorno


If Len(MeseCorrente) = 1 Then MeseCorrente = "0" &
MeseCorrente
If Len(GiornoCorrente) = 1 Then GiornoCorrente = "0" &
GiornoCorrente

' Nome della sottocartella (AAAAMMGG)


NomeSubFolder = AnnoCorrente & MeseCorrente &
GiornoCorrente

' Aggiungi all'array dei nomi


arrFolderName(Cont) = NomeSubFolder

Next

' Per ogni sottocartella di quella principale controlla se il nome

28 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 29

60 SCRIPT
AMMINISTRATIVI
Controllo del numero d’istanze di un processo per Windows

' è uguale ad uno degli item dell'array


For Each subFolder In Folder.SubFolders

If subFolder.Name <>arrFolderName(0) And subFolder.Name <>


arrFolderName(1) And subFolder.Name <>arrFolderName(2) Then
' Cancella la sottocartella
subFolder.Delete
End If
Next

Set FSO = Nothing


Set subFolder = Nothing
Set Folder = Nothing

CONTROLLO DEL NUMERO


D’ISTANZE DI UN PROCESSO
Anche questo script, sebbene possa sembrare piuttosto partico-
lare, è frutto di una richiesta reale. In particolare, il problema
era quello di rilevare periodicamente il numero d’istanze di un
determinato processo (nell’esempio abbiamo utilizzato SVCHOST.EXE)
ed allertare l’amministratore quando tale numero risulta diver-
so da quello richiesto. Anche qui viene sfruttato WMI ed in par-
ticolare viene fatto uso della classe Win32_Process per ottene-
re il numero esatto d’istanze.

Option Explicit

Dim Processo ' Nome del processo da controllare


Dim Istanze ' Numero delle istanze
Dim strComputer ' Computer sul quale operare
Dim objWMIService ' Oggetto WMI
Dim ListaProcessi ' Collection della lista dei processi

I libri di ioPROGRAMMO/60 script amministrativi per Windows 29


007-014 02/02/07 14:56 Pagina 30

60 SCRIPT
AMMINISTRATIVI
per Windows Monitoring degli utenti

strComputer = "."
Processo = "svchost.exe"
Istanze = 3

' Ottieni l'elenco delle istanze del processo considerato


Set objWMIService = GetObject("winmgmts:" &
"{impersonationLevel=impersonate}!\\" & strComputer &
"\root\cimv2")
Set ListaProcessi = objWMIService.ExecQuery ("SELECT Name FROM
Win32_Process WHERE Name='" & Processo & "'")

' Controlla se il numero delle istanze trovate coincide


If ListaProcessi.Count <> Istanze Then
Wscript.Echo "Il numero delle istanze del processo " & Processo &
" non coincide!"
Else
Wscript.Echo "Il numero delle istanze del processo " & Processo &
" coincide!"
End If

Set objWMIService = Nothing


Set ListaProcessi = Nothing

MONITORING DEGLI UTENTI


Attraverso la classe WMI __InstanceOperationEvent possiamo
rilevare in tempo reale diversi cambiamenti che avvengono al-
l’interno di un sistema, specificando opportunamente le infor-
mazioni da monitorare. Qui stiamo controllando gli eventuali
cambiamenti che avvengono sugli utenti (in particolare cancel-
lazione e creazione). Per maggiori dettagli si riporta al sito del-
la Microsoft.

30 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 31

60 SCRIPT
AMMINISTRATIVI
Monitoring degli utenti per Windows

Nota: il controllo rimane attivo sino al riavvio del sistema o si-


no a quando non viene manualmente distrutto il processo wscript
o cscript relativo.

Option Explicit

Dim strComputer ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim colMonitoredEvents ' Collection degli eventi di monitoring
Dim objEventObject ' Generico item della collection
colMonitoredEvents
Dim Messaggio ' Stringa contenente i dettagli dell'evento
Dim objShell ' Oggetto Shell

Const EVENT_SUCCESS = 0

strComputer = "."

' Avvia il monitoring sulla creazione o eliminazione degli utenti


Set objWMIService = GetObject("winmgmts:\\" & strComputer &
"\root\cimv2")
Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceOperationEvent WITHIN
10 WHERE " _
& "Targetinstance ISA 'Win32_UserAccount'")

Set objShell = Wscript.CreateObject("Wscript.Shell")

' Attendi il verificarsi dell'evento


Do While True
Set objEventObject = colMonitoredEvents.NextEvent()

Select Case objEventObject.Path_.Class

I libri di ioPROGRAMMO/60 script amministrativi per Windows 31


007-014 02/02/07 14:56 Pagina 32

60 SCRIPT
AMMINISTRATIVI
per Windows Monitoring degli utenti

Case "__InstanceCreationEvent"
Messaggio = "E' stato creato l'utente: " &
UCase(objEventObject.TargetInstance.Name) & vbCrlf
Messaggio = Messaggio & "Ecco alcuni dettagli:" & vbCrlf
& "------------------------" & vbCrlf
Messaggio = Messaggio & "AccountType: " &
objEventObject.TargetInstance.AccountType & vbCrlf
Messaggio = Messaggio & "Description: " &
objEventObject.TargetInstance.Description & vbCrlf
Messaggio = Messaggio & "SID: " &
objEventObject.TargetInstance.SID

Wscript.Echo Messaggio
' Scrivi il messaggio nell'Application Log
objShell.LogEvent EVENT_SUCCESS, Messaggio

Case "__InstanceDeletionEvent"
Messaggio = "E' stato eliminato l'utente: " &
UCase(objEventObject.TargetInstance.Name) & vbCrlf
Messaggio = Messaggio & "Ecco alcuni dettagli:" & vbCrlf
& "------------------------" & vbCrlf
Messaggio = Messaggio & "AccountType: " &
objEventObject.TargetInstance.AccountType & vbCrlf
Messaggio = Messaggio & "Description: " &
objEventObject.TargetInstance.Description & vbCrlf
Messaggio = Messaggio & "SID: " &
objEventObject.TargetInstance.SID

Wscript.Echo Messaggio
' Scrivi il messaggio nell'Application Log
objShell.LogEvent EVENT_SUCCESS, Messaggio

End Select

32 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 33

60 SCRIPT
AMMINISTRATIVI
Monitoring dei gruppi per Windows

Loop

Set objWMIService = Nothing


Set colMonitoredEvents = Nothing
Set objEventObject = Nothing
Set objShell = Nothing

MONITORING DEI GRUPPI


Attraverso la classe WMI __InstanceOperationEvent possiamo
rilevare in tempo reale diversi cambiamenti che avvengono al-
l’interno di un sistema, specificando opportunamente le infor-
mazioni da monitorare. Qui stiamo controllando gli eventuali
cambiamenti che avvengono sui gruppi (in particolare cancella-
zione e creazione). Per maggiori dettagli si riporta al sito della
Microsoft.
Nota: il controllo rimane attivo sino al riavvio del sistema o si-
no a quando non viene manualmente distrutto il processo wscript
o cscript relativo.

Option Explicit

Dim strComputer ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim colMonitoredEvents ' Collection degli eventi da monitorare
Dim objEventObject ' Generico evento
Dim Messaggio ' Stringa che memeorizza i dettagli sull'evento
Dim objShell ' Oggetto Shell

Const EVENT_SUCCESS = 0

strComputer = "."

I libri di ioPROGRAMMO/60 script amministrativi per Windows 33


007-014 02/02/07 14:56 Pagina 34

60 SCRIPT
AMMINISTRATIVI
per Windows Monitoring dei gruppi

' Avvia il monitoring sulla creazione o eliminazione degli utenti


Set objWMIService = GetObject("winmgmts:\\" & strComputer &
"\root\cimv2")
Set colMonitoredEvents = objWMIService.ExecNotificationQuery _
("SELECT * FROM __InstanceOperationEvent WITHIN
10 WHERE " _
& "Targetinstance ISA 'Win32_Group'")

Set objShell = Wscript.CreateObject("Wscript.Shell")

' Attendi il verificarsi dell'evento


Do While True
Set objEventObject = colMonitoredEvents.NextEvent()

Select Case objEventObject.Path_.Class


Case "__InstanceCreationEvent"
Messaggio = "E' stato creato il gruppo: " &
UCase(objEventObject.TargetInstance.Name) & vbCrlf
Messaggio = Messaggio & "Ecco alcuni dettagli:" & vbCrlf
& "------------------------" & vbcrlf
Messaggio = Messaggio & "Descrizione: " &
objEventObject.TargetInstance.Description & vbCrlf
Messaggio = Messaggio & "SID: " &
objEventObject.TargetInstance.SID

Wscript.Echo Messaggio
objShell.LogEvent EVENT_SUCCESS, Messaggio

Case "__InstanceDeletionEvent"
Messaggio = "E' stato eliminato il gruppo: " &
UCase(objEventObject.TargetInstance.Name) & vbCrlf
Messaggio = Messaggio & "Ecco alcuni dettagli:" & vbCrlf
& "------------------------" & vbCrlf

34 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 35

60 SCRIPT
AMMINISTRATIVI
Monitoring della creazione/cancellazione di file per Windows

Messaggio = Messaggio & "Descrizione: " &


objEventObject.TargetInstance.Description & vbCrlf
Messaggio = Messaggio & "SID: " &
objEventObject.TargetInstance.SID

Wscript.Echo Messaggio
objShell.LogEvent EVENT_SUCCESS, Messaggio

End Select
Loop

Set objWMIService = Nothing


Set colMonitoredEvents = Nothing
Set objEventObject = Nothing
Set objShell = Nothing

MONITORING DELLA
CREAZIONE/CANCELLAZIONE
DI FILE
Abbiamo visto che, attraverso la classe WMI __InstanceOpera-
tionEvent, possiamo rilevare in tempo reale diversi cambiamen-
ti che avvengono all’interno di un sistema, specificando oppor-
tunamente le informazioni da monitorare. Ecco di seguito uno
script piuttosto particolare perché permette di tenere sotto con-
trollo i cambiamenti che avvengono all’interno di una cartella (nel-
l’esempio C:\Windows). Per maggiori dettagli si riporta al sito del-
la Microsoft
Nota: il controllo rimane attivo sino al riavvio del sistema o si-
no a quando non viene manualmente distrutto il processo wscript
o cscript relativo.

Option Explicit

I libri di ioPROGRAMMO/60 script amministrativi per Windows 35


007-014 02/02/07 14:56 Pagina 36

60 SCRIPT
AMMINISTRATIVI
per Windows Monitoring della creazione/cancellazione di file

Dim strComputer ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim colMonitoredEvents ' Collection degli eventi monitorati
Dim objEventObject ' Generico evento della collection
colMonitoredEvents
Dim NameFile ' Nome del file
Dim FileNamePos ' Variabile d'appoggio
Dim FSO ' Oggetto File System Object
Dim strPartComp ' Variabile d'appoggio
Dim FilePath ' Percorso file
Dim objFile ' Generico oggetto di tipo 'file'
Dim objShell ' Oggetto Shell

Const EVENT_SUCCESS = 0

strComputer = "."

' Crea l'oggetto FSO per ottenere info sui file creati/eliminati
Set FSO = CreateObject("Scripting.FileSystemObject")

' Crea l'oggetto WMI che servirà a monitorare la creazione di un file


Set objWMIService = GetObject("winmgmts:\\" & strComputer &
"\root\cimv2")

' Avvia la query che consentirà di monitorare la creazione di file


all'interno di una cartella. Per impostazione predefinita è
C:\Windows

Set colMonitoredEvents = objWMIService.ExecNotificationQuery


("SELECT * FROM __InstanceOperationEvent WITHIN 10 WHERE " _
& "Targetinstance ISA 'CIM_DirectoryContainsFile'
AND TargetInstance.GroupComponent= " _

36 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 37

60 SCRIPT
AMMINISTRATIVI
Monitoring della creazione/cancellazione di file per Windows

& "'Win32_Directory.Name=""c:\\\\Windows""'")

Set objShell = Wscript.CreateObject("Wscript.Shell")

' Attendi che si verifichi l'evento di creazione o cancellazione di un file


Do While True
Set objEventObject = colMonitoredEvents.NextEvent()

' Preleva il nome del file eliminando la parte non necessaria...


FileNamePos =
Instr(objEventObject.TargetInstance.PartComponent,"=")

NameFile =
Mid(objEventObject.TargetInstance.PartComponent,FileNamePos+1,
Len(objEventObject.TargetInstance.PartComponent))

' Sostituisci i \\ con \


NameFile = Replace(NameFile, "\\","\")

' Mostra l'opportuno msg all'utente


Select Case objEventObject.Path_.Class
' CREAZIONE NUOVO FILE...
Case "__InstanceCreationEvent"

strPartComp =
objEventObject.TargetInstance.PartComponent
FilePath = Split(strPartComp, "CIM_DataFile.Name=")(1)
FilePath = Replace(FilePath, """", "")
FilePath = Replace(FilePath, "\\", "\")

Set objFile = FSO.GetFile(FilePath)


Wscript.Echo "E' stato creato un nuovo file: " &
ObjFile.Name

I libri di ioPROGRAMMO/60 script amministrativi per Windows 37


007-014 02/02/07 14:56 Pagina 38

60 SCRIPT
AMMINISTRATIVI
per Windows Monitoring dei servizi

objShell.LogEvent EVENT_SUCCESS, "E' stato creato un


nuovo file: " & ObjFile.Name

' ELIMINAZIONE FILE


Case "__InstanceDeletionEvent"

strPartComp =
objEventObject.TargetInstance.PartComponent
FilePath = Split(strPartComp, "CIM_DataFile.Name=")(1)
FilePath: = Replace(FilePath, """", "")
FilePath = Replace(FilePath, "\\", "\")

Wscript.Echo "E' stato eliminato il file: " & FilePath


objShell.LogEvent EVENT_SUCCESS, "E' stato eliminato
il file: " & FilePath
End Select

Loop

Set objWMIService = Nothing


Set FSO = Nothing
Set colMonitoredEvents = Nothing
Set objEventObject = Nothing
Set objFile = Nothing
Set objShell = Nothing

MONITORING DEI SERVIZI


Per essere allertati in tempo reale sul cambio di stato di un ser-
vizio, possiamo utilizzare, anche in questo caso, la classe WMI
mostrata negli analoghi script. In quest’esempio, però, è stato
parametrizzata la query che attiva questo controllo, permetten-

38 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 39

60 SCRIPT
AMMINISTRATIVI
Monitoring dei servizi per Windows

do all’amministratore di decidere quali servizi monitorare e qua-


le sia il passaggio di stato da considerare. Attraverso i commen-
ti inseriti dovrebbe essere comunque piuttosto banale modifica-
re queste righe di codice per adattarlo alle proprie esigenze.
Nota: il controllo rimane attivo sino al riavvio del sistema o si-
no a quando non viene manualmente distrutto il processo wscript
o cscript relativo.

Option Explicit

Dim strComputer ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim colMonitoredEvents ' Collection degli eventi
da monitorare
Dim objEventObject ' Generico evento nella collection
colMonitoredEvents
Dim ServiceStateToMon ' Stato del servizio da monitorare
Dim ServiceStartModeToMon ' Start Mode del servizio
da monitorare
Dim ServiceQuery ' Query WMI
Dim objShell ' Oggetto WMI

strComputer = "."

' Monitor delo stato dei servizi:


' ServiceStateToMon = "Stopped" -> Solo servizi che risultano
fermati
' "Running" -> Solo servizi che risultano avviati
' ServiceStartModeToMon = "Auto" -> Solo servizi in start Automatic
' "Manual" -> Solo servizi in start Manual

Const EVENT_SUCCESS = 0

I libri di ioPROGRAMMO/60 script amministrativi per Windows 39


007-014 02/02/07 14:56 Pagina 40

60 SCRIPT
AMMINISTRATIVI
per Windows Monitoring dei servizi

ServiceStateToMon = "Stopped"
ServiceStartModeToMon = "Auto"

' Ottieni la lista dei servizi


Set objWMIService = GetObject("winmgmts:\\" & strComputer &
"\root\cimv2")

' Raccogli tutti gli eventi legati a servizi in automatic che vengono
fermati

Select Case ServiceStateToMon


Case "Stopped"
ServiceQuery = "TargetInstance.State='Stopped'"
Case "Running"
ServiceQuery = "TargetInstance.State='Running'"
Case Else
Wscript.Echo "Errore nella configurazione dei parametri"
Wscript.Quit
End Select

Select Case ServiceStartModeToMon


Case "Auto"
ServiceQuery = ServiceQuery & " AND
TargetInstance.StartMode='Auto'"
Case "Manual"
ServiceQuery = ServiceQuery & " AND
TargetInstance.StartMode='Manual'"
Case Else
Wscript.Echo "Errore nella configurazione dei parametri"
Wscript.Quit
End Select

Set colMonitoredEvents = objWMIService.ExecNotificationQuery _

40 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 41

60 SCRIPT
AMMINISTRATIVI
Monitoring dei servizi per Windows

("SELECT * FROM __InstanceOperationEvent WITHIN


10 WHERE TargetInstance

ISA " _
& "'Win32_Service' AND (PreviousInstance.State <>
TargetInstance.State) AND " &

ServiceQuery)

Set objShell = Wscript.CreateObject("Wscript.Shell")

' Controlla il cambio di stato del servizio secondo i criteri fissati


Do While True
Set objEventObject = colMonitoredEvents.NextEvent()

Select Case objEventObject.Path_.Class


Case "__InstanceModificationEvent"
Wscript.Echo "Il servizio: " &
UCase(objEventObject.TargetInstance.Name) & " è stato

fermato!"
' Scrivi il messaggio nell'Application Log
objShell.LogEvent EVENT_SUCCESS, "Il servizio: " &
UCase(objEventObject.TargetInstance.Name) & " è stato fermato!"
End Select
Loop

Set objWMIService = Nothing


Set colMonitoredEvents = Nothing
Set objEventObject = Nothing
Set objShell = Nothing

I libri di ioPROGRAMMO/60 script amministrativi per Windows 41


007-014 02/02/07 14:56 Pagina 42

60 SCRIPT
AMMINISTRATIVI
per Windows Monitoring delle Server Connection

MONITORING
DELLE SERVER CONNECTION
L’utilizzo della classe WMI __InstanceOperationEvent è parti-
colarmente utile anche per rilevare tentativi d’intrusione. Ecco
un “semplice” esempio che rileva i tentativi di connessione ad
una qualunque risorsa del sistema considerato.
Nota: il controllo rimane attivo sino al riavvio del sistema o si-
no a quando non viene manualmente distrutto il processo wscript
o cscript relativo.

Option Explicit

Dim strComputer ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim colMonitoredEvents ' Collection degli eventi da monitorare
Dim Messaggio ' Messaggio con i dettagli dell'evento
Dim objEventObject ' Generico evento
Dim objShell ' Oggetto Shell

Const EVENT_SUCCESS = 0

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer &


"\root\cimv2")

Set colMonitoredEvents = objWMIService.ExecNotificationQuery _


("SELECT * FROM __InstanceOperationEvent WITHIN 10 WHERE " _
& "Targetinstance ISA 'Win32_ServerConnection'")

Set objShell = Wscript.CreateObject("Wscript.Shell")

' Attendi il verificarsi degli eventi...

42 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 43

60 SCRIPT
AMMINISTRATIVI
Monitoring delle Server Connection per Windows

Do While True
Set objEventObject = colMonitoredEvents.NextEvent()

Select Case objEventObject.Path_.Class


Case "__InstanceCreationEvent"
Messaggio = "C'è una nuova sessione da remoto - Utente
Remoto: " & UCase(objEventObject.TargetInstance.UserName)
& vbCrlf

Messaggio = Messaggio & "Ecco alcuni dettagli:" & vbCrlf


& "------------------------" & vbCrlf
Messaggio = Messaggio & "Computer Name: " &
objEventObject.TargetInstance.ComputerName & vbCrlf
Messaggio = Messaggio & "Risorse aperte: " &
objEventObject.TargetInstance.ShareName & vbCrlf

Wscript.Echo Messaggio
objShell.LogEvent EVENT_SUCCESS, Messaggio

Case "__InstanceDeletionEvent"
Messaggio = "La sessione aperta da " &
UCase(objEventObject.TargetInstance.UserName) _
& " su " & objEventObject.TargetInstance.ShareName
& " è stata eliminata"
Wscript.Echo Messaggio
objShell.LogEvent EVENT_SUCCESS, Messaggio
End Select
Loop

Set objWMIService = Nothing


Set colMonitoredEvents = Nothing
Set objEventObject = Nothing
Set objShell = Nothing

I libri di ioPROGRAMMO/60 script amministrativi per Windows 43


007-014 02/02/07 14:56 Pagina 44

60 SCRIPT
AMMINISTRATIVI
per Windows Monitoring delle condivisioni

MONITORING DELLE
CONDIVISIONI
Oltre al controllo sulla creazione di Server Session, è possibile con-
trollare il tentativo di modifiche apportate alle condivisioni (crea-
zione, modifica e cancellazione). Anche questo esempio, come
i precedenti, sfrutta WMI.
Nota: il controllo rimane attivo sino al riavvio del sistema o si-
no a quando non viene manualmente distrutto il processo wscript
o cscript relativo.

Option Explicit

Dim strComputer ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim colMonitoredEvents ' Collection eventi da monitorare
Dim objEventObject ' Generico evento
Dim Messaggio ' Messaggio contenente i dettagli
Dim objShell ' Oggetto Shell

Const EVENT_SUCCESS = 0

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer &


"\root\cimv2")

Set colMonitoredEvents = objWMIService.ExecNotificationQuery _


("SELECT * FROM __InstanceOperationEvent WITHIN
10 WHERE " _
& "Targetinstance ISA
'Win32_LogicalShareSecuritySetting'")

Set objShell = Wscript.CreateObject("Wscript.Shell")

44 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 45

60 SCRIPT
AMMINISTRATIVI
Monitoring delle condivisioni per Windows

' Attendi che si verifichi l'evento


Do While True
Set objEventObject = colMonitoredEvents.NextEvent()

Select Case objEventObject.Path_.Class


Case "__InstanceCreationEvent"
Messaggio = "E' stata creata la share: " &
UCase(objEventObject.TargetInstance.Name) & vbCrlf
Messaggio = Messaggio & "Ecco alcuni dettagli:" &
vbCrlf & "------------------------" & vbCrlf
Messaggio = Messaggio & "Descrizione: " &
objEventObject.TargetInstance.Description & vbCrlf

Wscript.Echo Messaggio
objShell.LogEvent EVENT_SUCCESS, Messaggio

Case "__InstanceDeletionEvent"
Messaggio = "E' stata cancellata la share: " &
UCase(objEventObject.TargetInstance.Name) & vbCrlf
Messaggio = Messaggio & "Ecco alcuni dettagli:" & vbCrlf
& "------------------------" & vbCrlf
Messaggio = Messaggio & "Descrizione: " &
objEventObject.TargetInstance.Description & vbCrlf

Wscript.Echo Messaggio
objShell.LogEvent EVENT_SUCCESS, Messaggio
End Select
Loop

Set objEventObject = Nothing


Set colMonitoredEvents = Nothing
Set objWMIService = Nothing
Set objShell = Nothing

I libri di ioPROGRAMMO/60 script amministrativi per Windows 45


007-014 02/02/07 14:56 Pagina 46

60 SCRIPT
AMMINISTRATIVI
per Windows Elencare le condivisioni di più server

ELENCARE LE CONDIVISIONI
DI PIÙ SERVER
Questo script consente di ottenere un file .CSV con la lista del-
le condivisioni di tutti i server indicati all’interno del file di testo
ElencoServer.txt. Come molti altri listati, si serve di WMI e più pre-
cisamente della classe Win32_Share.

Option Explicit

Dim ServerCorrente ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim lstCondivisioni ' Lista delle condivisioni
Dim Condivisione ' Generica condivisione
Dim ElencoCondivisioni ' Stringa contenente i dettagli
da visualizzare
Dim FSO ' Oggetto File System Object
Dim LeggiFile ' Puntatore al file contenente i server su
cui operare
Dim LogFile ' Puntatore al file di log

' Preleva l'elenco dei server su cui effettuare il controllo


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Controlla se il file di log esiste o se occorre crearlo


If (FSO.FileExists("ElencoShare.csv")) Then
Set LogFile = FSO.OpenTextFile("ElencoShare.csv",8)
Else
Set LogFile = FSO.CreateTextFile("ElencoShare.csv", True)
End If

' Leggi il file con l'elenco dei server e, per ognuno, cerca
le condivisioni

46 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 47

60 SCRIPT
AMMINISTRATIVI
Salvare l’elenco delle condivisioni per Windows

LogFile.WriteLine "SERVER;NOME;PERCORSO"

Do While Not LeggiFile.AtEndOfStream


ServerCorrente = LeggiFile.ReadLine

' Ricava l'elenco delle condivisioni


Set objWMIService = GetObject("winmgmts:\\" & ServerCorrente
& "\root\cimv2")
Set lstCondivisioni = objWMIService.InstancesOf("Win32_Share")

' Crea la stringa inserire nel file di log


For Each Condivisione In lstCondivisioni
ElencoCondivisioni = Condivisione.Name & ";" &
Condivisione.Path
' Inserisci i dati nel file di log
LogFile.WriteLine ServerCorrente & ";" & ElencoCondivisioni
Next
Loop

LeggiFile.Close
LogFile.Close

Set objWMIService = Nothing


Set lstCondivisioni = Nothing
Set FSO = Nothing
Set LeggiFile = Nothing
Set LogFile = Nothing

SALVARE L’ELENCO
DELLE CONDIVISIONI
L’elenco delle condivisioni di un sistema è contenuto all’interno
di un’opportuna chiave del Registry indicata in testa allo script

I libri di ioPROGRAMMO/60 script amministrativi per Windows 47


007-014 02/02/07 14:56 Pagina 48

60 SCRIPT
AMMINISTRATIVI
per Windows Salvare l’elenco delle condivisioni

seguente. Utilizzando la classe WMI StdRegProv quindi possia-


mo leggere la porzione del Registry ce ci serve allo scopo e sal-
varla in un file.
Nello script mostrato, per semplicità, non è stato inserito il sal-
vataggio del secondo ramo del Registry.

Option Explicit

' L'elenco delle condivisioni è contenuta sotto:


'
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\
LanmanServer\Shares
' Le informazioni di sicurezza sono sotto:
'
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\
LanmanServer\Shares\Security

Dim strComputer ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim colElencoShare() ' Array di share
Dim colElencoShare2() ' Array di share
Dim strKeyPath ' Percorso nel Registry
Dim oReg ' Oggetto Registry
Dim FSO ' Oggetto File System Object
Dim LogFile ' Puntatore al file di log
Dim ItemShare ' Generica share
Dim Cont ' Contatore
Dim Cont2 ' Contatore

Const HKEY_LOCAL_MACHINE = &H80000002:

strComputer = "."
strKeyPath =

48 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 49

60 SCRIPT
AMMINISTRATIVI
Salvare l’elenco delle condivisioni per Windows

"System\CurrentControlSet\Services\LanmanServer\Shares"

Set FSO = CreateObject("Scripting.FileSystemObject")


' Controlla se il file di log esiste o occorre crearlo
If (FSO.FileExists("ElencoShare.log")) Then
Set LogFile = FSO.OpenTextFile("ElencoShare.log",8)
Else
Set LogFile = FSO.CreateTextFile("ElencoShare.log", True)
End If

' Crea l'oggetto per la scansione del Registry


Set oReg = GetObject("winmgmts:{impersonationLevel=
impersonate}!\\" & strComputer & "\root\default:StdRegProv")

' Leggi le impostazioni dal Registry (ossia l'elenco delle condivisioni)


oReg.EnumValues
HKEY_LOCAL_MACHINE,strKeyPath,colElencoShare

Cont = 0
For Each ItemShare In colElencoShare

oReg.GetMultiStringValue
HKEY_LOCAL_MACHINE,strKeyPath,colElencoShare(Cont),
ColElencoShare2
LogFile.WriteLine colElencoShare(Cont)
For Cont2 = 0 To Ubound(colElencoShare2)
If Cont2 = 0 Then
LogFile.Write colElencoShare2(Cont2)
Else
LogFile.Write "," & colElencoShare2(Cont2)
End If
Next
Cont = Cont + 1

I libri di ioPROGRAMMO/60 script amministrativi per Windows 49


007-014 02/02/07 14:56 Pagina 50

60 SCRIPT
AMMINISTRATIVI
per Windows Eseguire il ping verso un host con e senza WMI

LogFile.WriteLine
Next

LogFile.Close
Set FSO = Nothing
Set colElencoShare= Nothing
Set LogFile = Nothing
Set oReg = Nothing

ESEGUIRE IL PING VERSO


UN HOST CON E SENZA WMI
Per simulare un ping esistono diverse strade possibili. Una di
queste consiste nell’avviare il comando ping rilevandone l’out-
put ed analizzandolo per le azioni successive. Un metodo più
semplice e, forse, più diffuso, è quello di sfruttare l’apposita
classe WMI Win32_PingStatus.
Più avanti in questo script (ma anche in alcuni altri listati del li-
bro) è mostrata una tecnica in grado di avviare tool esterni (in
questo caso il comando PING) recuperandone l’output diretta-
mente dallo script.

Option Explicit

Dim strComputer ' Host di partenza


Dim ToHost ' Host di destinazione
Dim PingResults ' Risultati del ping
Dim PingResObj ' Generico elemento della collection PingResults
Dim objWMIService ' Oggetto WMI
Dim objWshShell ' Oggetto Shell
Dim cmdPingToHost ' Comando PING <Nome Host>

strComputer = "."

50 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 51

60 SCRIPT
AMMINISTRATIVI
Eseguire il ping verso un host con e senza WMI per Windows

ToHost = "127.0.0.1"

' -------------- METODO 1 --------------


' Connessione al namespace della macchina locale
Set objWMIService = GetObject("winmgmts:" &
"{impersonationLevel=impersonate}!\\" & strComputer &
"\root\cimv2")

' Esegui il ping verso l'host remoto


Set PingResults = objWmiService.ExecQuery("SELECT * FROM
Win32_PingStatus WHERE Address = '" + ToHost + "'")

For Each PingResObj In PingResults


' Se l'host risponde...
If PingResObj.StatusCode = 0 Then
Msgbox "Bytes: " & PingResObj.BufferSize & " Time (ms): " &
PingResObj.ResponseTime & " TTL (s): " &
PingResObj.ResponseTimeToLive
Else
Msgbox ToHost & " non risponde" & vbCrlf & "Status code: "
& PingResObj.StatusCode
End If
Next

' -------------- METODO 2 --------------


Set objWshShell = CreateObject( "WScript.Shell" )

cmdPingToHost = "PING " & ToHost


PingResults = objWshShell.Exec(cmdPingToHost).StdOut.ReadAll()

' Mostra i risultati


Msgbox PingResults

I libri di ioPROGRAMMO/60 script amministrativi per Windows 51


007-014 02/02/07 14:56 Pagina 52

60 SCRIPT
AMMINISTRATIVI
per Windows Creare un report delle corrispondenze Server – Indirizzo IP

Set PingResults = Nothing


Set objWmiService = Nothing
Set PingResObj = Nothing
Set objWshShell = Nothing

CREARE UN REPORT DELLE


CORRISPONDENZE SERVER –
INDIRIZZO IP
Servendoci di quanto visto nello script che illustra due metodi per
lanciare il comando ping verso un host, possiamo realizzarne
uno in grado di realizzare un log di tutte le corrispondenze No-
me Server – IP Address, prelevando i dati relativi ai nomi dei
server da un’apposito file di input. In pratica, il codice seguen-
te, per ogni sistema da “pingare”, lancia il comando verso tale
host e ne preleva l’output. A questo punto lo scansiona per tro-
vare la prima parentesi quadra che racchiude l’indirizzo IP. Se
non la trova dà errore, altrimenti cerca la parentesi quadra di
chiusura e, infine, con questi dati, estrae l’indirizzo IP che racchiu-
dono.

Option Explicit

Dim PingResults ' Stringa contenente l'output del comando PING


Dim ToHost ' Host di destinazione
Dim objWMIService ' Oggetto WMI
Dim objWshShell ' Oggetto Shell
Dim cmdPingToHost ' Comando PING <Nome Host>
Dim FSO ' Oggetto File System Object
Dim LeggiFile ' File di input
Dim LogFile ' File di log
Dim FirstBracket ' Prima parentesi quadra che contiene l'IP
Dim SecondBracket ' Seconda parentesi quadra che contiene l'IP

52 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 53

60 SCRIPT
AMMINISTRATIVI
Creare un report delle corrispondenze Server – Indirizzo IP per Windows

Dim IPAddress ' Indirizzo IP dell'host

Const wbemFlagReturnImmediately = &h10


Const wbemFlagForwardOnly = &h20

ToHost = "127.0.0.1"

Set objWshShell = CreateObject( "WScript.Shell" )

' Creiamo l'oggetto FSO


Set FSO = CreateObject("Scripting.FileSystemObject")

' Controlliamo l'esistenza del file di log


If (FSO.FileExists("ServerToIP.log")) Then
Set LogFile = FSO.OpenTextFile("ServerToIP.log",8)
Else
Set LogFile = FSO.CreateTextFile("ServerToIP.Log", True)
End If

' Apriamo il file di input


Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Leggiamo l'intero file di input


Do While Not LeggiFile.AtEndOfStream

' Host da risolvere


ToHost = LeggiFile.ReadLine

' Lanciamo il ping


cmdPingToHost = "PING " & ToHost
PingResults = objWshShell.Exec(cmdPingToHost).StdOut.ReadAll()

' Elabora i risultati

I libri di ioPROGRAMMO/60 script amministrativi per Windows 53


007-014 02/02/07 14:56 Pagina 54

60 SCRIPT
AMMINISTRATIVI
per Windows Creare un report delle corrispondenze Server – Indirizzo IP

FirstBracket = Instr(PingResults,"[")
If FirstBracket <> 0 Then
SecondBracket = InstrRev(PingResults,"]")
IPAddress = Mid(PingResults, FirstBracket+1, SecondBracket-
FirstBracket-1)
LogFile.WriteLine ToHost & ";" & IPAddress
Else
LogFile.WriteLine ToHost & ";Sconosciuto"
End If
Loop

LogFile.Close
LeggiFile.Close

Set PingResults = Nothing


Set objWshShell = Nothing
Set FSO = Nothing
Set LogFile = Nothing
Set LeggiFile = Nothing

WScript.Echo “Ho terminato…”

' ---------------------------------------------------------------------------------------
-------
' Nel caso il server supporti WMI, l’indirizzo IP può anche essere
ottenuto così:
' strComputer = "."
' Set objWMIService = GetObject( "winmgmts:\\" & strComputer &
"\root\cimv2")
' Set IPConfigSet = objWMIService.ExecQuery("SELECT IPAddress
FROM Win32_NetworkAdapterConfiguration" _
' & " WHERE IPEnabled = TRUE","WQL",
wbemFlagReturnImmediately + wbemFlagForwardOnly)

54 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 55

60 SCRIPT
AMMINISTRATIVI
Creare un report delle corrispondenze Server – MAC Address per Windows

' For Each IPConfig in IPConfigSet


' If Not IsNull(IPConfig.IPAddress) Then
' For I = LBound(IPConfig.IPAddress) To
UBound(IPConfig.IPAddress)
' IPAddress = IPConfig.IPAddress(i)
' Exit For
' Next
' End If
' Next
' Wscript.Echo IPAddress
' ---------------------------------------------------------------------------------------
-------

CREARE UN REPORT DELLE


CORRISPONDENZE SERVER –
MAC ADDRESS
Questo script è simile al precedente, ma permette di riportare l’e-
lenco dei MAC Address e la descrizione dell’adattatore di rete
rilevato.

Option Explicit

Dim Utente ' Utente per l'accesso al server


Dim Password ' Password per l'accesso al server
Dim ToHost ' Host di destinazione
Dim objWMIService ' Oggetto WMI
Dim objWshShell ' Oggetto Shell
Dim FSO ' Oggetto File System Object
Dim LeggiFile ' File di input
Dim LogFile ' File di log
Dim MACAddresses ' Collection di MAC Address
Dim MACAddress ' Stringa che memorizza il MAC Address

I libri di ioPROGRAMMO/60 script amministrativi per Windows 55


007-014 02/02/07 14:56 Pagina 56

60 SCRIPT
AMMINISTRATIVI
per Windows Creare un report delle corrispondenze Server – MAC Address

corrente
Dim Descrizione ' Stringa che memorizza la descizione
dell'interfaccia di rete
Dim objMacAddress ' Generico item della collection
di MAC Address
Dim objLocator ' Oggetto WMI

Const wbemFlagReturnImmediately = &H10


Const wbemFlagForwardOnly = &H20

ToHost = "127.0.0.1"

Utente = "MyDomain\Utente"
Password = "Password"

Set objWshShell = CreateObject( "WScript.Shell" )

' Creiamo l'oggetto FSO


Set FSO = CreateObject("Scripting.FileSystemObject")
' Controlliamo l'esistenza del file di log
If (FSO.FileExists("ServerMACAdrress.csv")) Then
Set LogFile = FSO.OpenTextFile("ServerMACAddress.csv",8)
Else
Set LogFile = FSO.CreateTextFile("ServerMACAddress.csv", True)
End If

' Apriamo il file di input


Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Scrivi l'intestazione del file di log


LogFile.WriteLine "SERVER;MAC ADDRESS;DESCRIZIONE"

' Leggiamo l'intero file di input

56 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 57

60 SCRIPT
AMMINISTRATIVI
Creare un report delle corrispondenze Server – MAC Address per Windows

Do While Not LeggiFile.AtEndOfStream

ToHost = "-"
MACAddress = "-"
Descrizione = "-"

' Host da contattare


ToHost = LeggiFile.ReadLine

' Collegati al server corrente e preleva il MAC ADDRESS


Set objLocator = CreateObject("WbemScripting.SwbemLocator")
Set objWMIService = objLocator.ConnectServer(ToHost,
"root\cimv2", Utente, Password)

Set MACAddresses = objWMIService.ExecQuery("SELECT


MacAddress, Description FROM "

_
& "Win32_NetworkAdapterConfiguration WHERE
IPEnabled=True","WQL",

wbemFlagReturnImmediately + wbemFlagForwardOnly)

On Error Resume Next

For Each objMacAddress In MACAddresses


MACAddress = objMacAddress.MacAddress
Descrizione = objMacAddress.Description
LogFile.WriteLine ToHost & ";" & MACAddress & ";" &
Descrizione
Next

Loop

I libri di ioPROGRAMMO/60 script amministrativi per Windows 57


007-014 02/02/07 14:56 Pagina 58

60 SCRIPT
AMMINISTRATIVI
per Windows Ricercare una particolare applicazione DCOM

LogFile.Close
LeggiFile.Close

Set objWshShell = Nothing


Set FSO = Nothing
Set LogFile = Nothing
Set LeggiFile = Nothing
Set objWMIService = Nothing
Set objWshShell = Nothing
Set objLocator = Nothing
Set MACAddresses = Nothing

Wscript.Echo "Ho terminato..."

RICERCARE UNA PARTICOLARE


APPLICAZIONE DCOM
Quando alcune applicazioni DCOM sono impostate in maniera
errata, può accadere che registrino all’interno dell’Event Log,
opportuni messaggi di errori che indicano però il CLSID dell’ap-
plicazione che sta causando problemi. Per correggere queste
anomalie, un metodo è quello di lanciare il tool DCOMCNFG e
cercare il CLSID che identifica l’applicativo. Un metodo più sem-
plice è lanciare questo script seguito dal CLSID da ricercare.

Option Explicit

Dim strComputer ' Computer sul quale operare


Dim DCOMApp ' Memorizza il CLSID dell'applicazione DCOM
Dim colItems ' Collection DCOMApplication
Dim objWMIService ' Oggetto WMI
Dim objItem ' Generico item della collection colItems
strComputer = "."

58 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 59

60 SCRIPT
AMMINISTRATIVI
Inviare una mail con e senza parametri per Windows

If Wscript.Arguments.Count = 0 Then
DCOMApp = Inputbox ("Inserire il CLSID dell'applicazione:",
"Inserimento DCOM CLSID")
Else
' Leggi l’argomento passato allo script che indica il CLSID
DCOMApp = Wscript.Arguments(0)
End If

Set objWMIService = GetObject("winmgmts:" _


& "{impersonationLevel=impersonate}!\\" & strComputer &
"\root\cimv2")

Set colItems = objWMIService.ExecQuery("Select AppID, Name FROM


Win32_DCOMApplication WHERE AppID= '" & DCOMApp & "'")

' Ricerca l'applicazione DCOM con l'ID passato


For Each objItem In colItems
Wscript.Echo "L'applicazione DCOM con ID " & objItem.AppID &
"è " & objItem.Name
Next

Set objWMIService = Nothing


Set colItems = Nothing
Set objItem = Nothing

INVIARE UNA MAIL


CON E SENZA PARAMETRI
Windows XP e Windows 2000 hanno sostituito a CDONTS l’og-
getto CDO per l’invio delle mail. Questo script, opportunamen-
te modificato sulla base di un’analogo codice fornito dalla Mi-
crosoft, permette di rendere più flessibile l’invio di una mail,
consentendo anche l’inserimento di un allegato. La particola-

I libri di ioPROGRAMMO/60 script amministrativi per Windows 59


007-014 02/02/07 14:56 Pagina 60

60 SCRIPT
AMMINISTRATIVI
per Windows Inviare una mail con e senza parametri

rità nell’uso di questo script è la presenza di parametri di de-


fault (contenuti all’interno del codice stesso) e di parametri pas-
sati allo script. In sostanza, quando un parametro non viene
specificato, lo script lo preleva direttamente da quelli di default
(un esempio è il nome del server e la porta SMTP solitamente sem-
pre preimpostati). Inoltre, per consentire una maggiore efficien-
za con quest’operazione, è stato implementato il controllo sul-
l’esistenza del file allegato prima dell’invio. Per ragioni di leggi-
bilità e chiarezza del codice mostrato, i nomi dei parametri da pas-
sare da command line, potrebbero sembrare troppo lunghi e, di
conseguenza, scomodi. In tal caso si consiglia di modificarli con
stringhe più brevi (ad esempio potremmo mettere TO al posto di
MAILTO) facendo però attenzione a modificare sia il nome del-
le variabili di default che quelli inseriti all’interno dei rispettivi
controlli sui parametri d’input.

Option explicit

Dim MailMittente ' Mail del mittente


Dim DescrizioneMittente ' Descrizione del mittente
Dim Mittente ' Descrizione mittente e mail
Dim Destinatario ' Mail del destinatario
Dim FSO ' Oggetto File System Object
Dim Oggetto ' Oggetto della mail
Dim SMTPserver ' Server SMTP
Dim Testo ' Testo della mail
Dim AttachmentFile ' Allegato della mail
Dim objEmail ' Oggetto CDO.Message
Dim TotArgs ' Numero argomenti passati
Dim Cont ' Contatore

Const SMTP_PORT = 25

60 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 61

60 SCRIPT
AMMINISTRATIVI
Inviare una mail con e senza parametri per Windows

' Controlla se sono stati passati sufficienti argomenti. Gli argomenti


vengono
' passati attraverso i seguenti parametri:
'
' MailFrom = Mail del mittente:
' DescrFrom = Descrizione del mittente (es.: Nome Cognome)
' MailTo = Mail del destinatario
' Subject = Oggetto della mail
' BodyMsg = Testo della mail
' SMTPServer = Nome del server di posta per l'invio della mail
' Attach = Allegato (="NULL" nel caso non ci fossero allegati)

' Utilizzare lo script in questo modo:


' Lanciarlo con i parametri necessari specificati in questo modo:
' InvioMail.vbs /MailFrom:francesco.lippo@email.it
/DescrFrom:Francesco ...
' Per i parametri non specificati verranno presi da quelli di default

' Valorizziamo i parametri di default

MailMittente = "MAIL DEL MITTENTE"


DescrizioneMittente = "DESCRIZIONE DEL MITTENTE"
Mittente = DescrizioneMittente & " <" & MailMittente & ">"
Destinatario = "MAIL DEL DESTINATARIO"
Oggetto = "OGGETTO DELLA MAIL"
Testo = "TESTO DELLA MAIL"
SMTPServer = "NOME DEL SERVER SMTP"
AttachmentFile = "NULL"

' Imposta i parametri da utilizzare sfruttando quelli passati


' e quelli di default

If Wscript.Arguments.Named.Exists("MailFrom") Then MailMittente

I libri di ioPROGRAMMO/60 script amministrativi per Windows 61


007-014 02/02/07 14:56 Pagina 62

60 SCRIPT
AMMINISTRATIVI
per Windows Inviare una mail con e senza parametri

= Wscript.Arguments.Named("MailFrom")
If Wscript.Arguments.Named.Exists("DescrFrom") Then
DescrizioneMittente = Wscript.Arguments.Named("DescrFrom")
If Wscript.Arguments.Named.Exists("MailTo") Then Destinatario =
Wscript.Arguments.Named("MailTo")
If Wscript.Arguments.Named.Exists("Subject") Then Oggetto =
Wscript.Arguments.Named("Subject")
If Wscript.Arguments.Named.Exists("BodyMsg") Then Testo =
Wscript.Arguments.Named("BodyMsg")
If Wscript.Arguments.Named.Exists("SMTPServer") Then SMTPServer
= Wscript.Arguments.Named("SMTPServer")
If Wscript.Arguments.Named.Exists("Attach") Then AttachmentFile =
Wscript.Arguments.Named("Attach")

Mittente = MailMittente & " <" & DescrizioneMittente & ">"

' Creazione oggetto CDO


Set objEmail = CreateObject("CDO.Message")

' Impostazione dei campi utili all'invio


With objEmail

.From = Mittente
.To = Destinatario
.Subject = Oggetto
.Textbody = Testo

.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/sendusing") =
2

.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/smtpserver") =

62 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 63

60 SCRIPT
AMMINISTRATIVI
Inviare una mail con e senza parametri per Windows

SMTPServer

.Configuration.Fields.Item _
("http://schemas.microsoft.com/cdo/configuration/
smtpserverport") = SMTP_PORT

' Controlla l'ultimo parametro che si riferisce all'allegato.


' Se risulta essere pari a NULL, allora non ci sono allegati.
If AttachmentFile <> "NULL" Then
Set FSO = CreateObject("Scripting.FileSystemObject")
' Verifica l'esistenza del file da allegare
If FSO.FileExists(AttachmentFile) Then
.AddAttachment AttachmentFile
Else
Wscript.Echo "Il file " & AttachmentFile & " che si vuol
inviare come allegato non esiste!"
Wscript.Echo "L'invio della mail è stato interrotto..."
Wscript.Quit
End If
End If

' Update informazioni ed invio mail


.Configuration.Fields.Update
.Send
End With

' Visualizza messaggio di conferma


Msgbox "La mail è stata inviata.", vbOkonly, "Informazioni"

Set objEMail = Nothing


Set FSO = Nothing

I libri di ioPROGRAMMO/60 script amministrativi per Windows 63


007-014 02/02/07 14:56 Pagina 64

60 SCRIPT
AMMINISTRATIVI
per Windows Intercettare l’evento SHUTDOWN

INTERCETTARE
L’EVENTO SHUTDOWN
Per intercettare lo spegnimento di un server possiamo lanciare
una query asincrona sfruttando WMI. Malgrado l’utilità di que-
sto script possa essere “dubbia”, credo sia interessante com-
prenderne il funzionamento per imparare ad utilizzare gli uti-
lissimi oggetti SwbemSink di WMI.

Option Explicit

Dim strComputer ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim ObjSink ' Oggetto WMI SINK

strComputer = "."
Set objWMIService =
GetObject("winmgmts:{impersonationLevel=impersonate,
(Security)}!\\" & strComputer & "\root\cimv2")

' Crea l’oggetto swbemsink ed avvia la query asincrona


Set ObjSink =
Wscript.CreateObject("wbemscripting.swbemsink","objsink_")
objWMIService.ExecNotificationQueryAsync ObjSink, "SELECT *
FROM Win32_ComputerShutdownEvent"

' Attendi il verificarsi dell'evento...


While True
Wscript.Echo "Resto in attesa..."
Wscript.Sleep 1000
Wend

Sub Objsink_OnObjectReady(obj, ctx)


Wscript.Echo "Shutdown event!"

64 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 65

60 SCRIPT
AMMINISTRATIVI
SQL Server Connection per Windows

End Sub

Set objWMIService = Nothing


Set ObjSink = Nothing

SQL SERVER CONNECTION


Ecco un semplice script che legge una tabella da SQL Server. In
realtà, la parte probabilmente più “difficile” da implementare è
quella che relativa all’impostazione dei parametri di connessio-
ne al DB (utente, password, tabella, ecc.). Una volta stabilita la
connessione ad esso, tutto si traduce drasticamente nelle “so-
lite” operazioni SQL compiute su un qualunque DB.

Option Explicit

Dim FSO ' Oggetto File System Object


Dim FileRubrica ' File che conterrà i risultati
Dim Conn ' Oggetto ADODB.Connection
Dim Tabella ' Tabella di SQL Server

' Imposta i parametri per la connessione al server SQL


Const UID = "User"
Const PWD = "Password"
Const Driver = "{SQL Server}"
Const Database = "TabellaSQL"
Const Server = "."

' Controlla l'esistenza del file di log. Crealo nel


' caso non esistesse.
Set FSO = CreateObject("Scripting.FileSystemObject")

If (FSO.FileExists("Rubrica.log")) Then

I libri di ioPROGRAMMO/60 script amministrativi per Windows 65


007-014 02/02/07 14:56 Pagina 66

60 SCRIPT
AMMINISTRATIVI
per Windows SQL Server Connection

Set FileRubrica= FSO.OpenTextFile("Rubrica.log",8)


Else
Set FileRubrica= FSO.CreateTextFile("Rubrica.log", True)
End If

' Connettiti al DB SQL Server, sfruttando le credenziali settate in UID e


PWD
Set Conn = CreateObject("ADODB.Connection")
Conn.Open "Driver={SQL Server};Server=" & Server & ";UID=" & UID
& ";Pwd=" & PWD & ";Database=" & Database & ""

' Avvia la query di controllo dei terminali In errore


QueryStr = "SELECT Nome_Impiegato, Mail FROM Rubrica"
Set Tabella = Conn.Execute(QueryStr)

' Leggi l'intera tabella e scrivi nel file i risultati


FileRubrica.WriteLine "NOME IMPIEGATO;MAIL"

Do While Not Tabella.Eof


FileRubrica.WriteLine Tabella.Fields("Nome_Impiegato") & ";" &
Tabella.Fields("Mail")
' Passa al record successivo
Tabella.MoveNext
Loop

FileRubrica.Close

Set FSO = Nothing


Set FileRubrica = Nothing
Set Tabella = Nothing
Set Conn = Nothing

66 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 67

60 SCRIPT
AMMINISTRATIVI
DBF Connection per Windows

DBF CONNECTION
In alcune realtà esistono ancora i vecchi archivi DBF. Anche se ap-
parentemente possono costituire un problema, la loro gestio-
ne non è molto diversa da quanto visto in precedenza. Pertan-
to non dovrebbe essere complicato intuirne le differenze.

Option Explicit
Dim FSO ' Oggetto File System Object
Dim FileRubrica ' File che conterrà i risultati
Dim Conn ' Oggetto ADODB.Connection
Dim Tabella ' Tabella (archivio DBF)
Dim Path ' Percorso del file DBF
Dim OpenDBFConn ' Oggetto ADODB.Connection
Dim QueryStr ' Stringa che identifica la query al DB

Path = "\\Server\C$\Archivio\"

' Controlla l'esistenza del file di log.


' Nel caso non esista, crealo...
Set FSO = CreateObject("Scripting.FileSystemObject")

If (FSO.FileExists("Rubrica.log")) Then
Set FileRubrica= FSO.OpenTextFile("Rubrica.log",8)
Else
Set FileRubrica= FSO.CreateTextFile("Rubrica.log", True)
End If

' Connettiti al DB LOG.DBF


Conn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & Path & ";"& _
"Extended Properties=""DBASE IV;"";"

Set OpenDBFConn = Conn

I libri di ioPROGRAMMO/60 script amministrativi per Windows 67


007-014 02/02/07 14:56 Pagina 68

60 SCRIPT
AMMINISTRATIVI
per Windows Impostare l’expiration date su un gruppo di utenti

' Imposta la stringa per la lettura del file Rubrica.dbf


' Per ipotesi viene letto tutto il DB
QueryStr = "Select Nome_Impiegato, Mail FROM [Rubrica#dbf]"

' Avvia la query


Set Tabella = Conn.Execute(QueryStr)

' Leggi l'intera tabella e scrivi nel file i risultati


FileRubrica.WriteLine "NOME IMPIEGATO;MAIL"

' Scrivi il risultato in un file CSV


Do While Not Tabella.Eof
FileRubrica.WriteLine Tabella.Fields("Nome_Impiegato") & ";" &
Tabella.Fields("Mail")
' Passa al record successivo
Tabella.MoveNext
Loop

FileRubrica.Close

Set FSO = Nothing


Set FileRubrica = Nothing
Set Tabella = Nothing
Set Conn = Nothing
Set OpenDBFConn = Nothing

IMPOSTARE L’EXPIRATION
DATE SU UN GRUPPO DI UTENTI
Questo script utilizza ADSI per impostare l’expiration date di un
gruppo di utenti specificati all’interno di un file d’input. Lo script
preleva dal file ElencoDN.txt tutti i Distinguished Name degli

68 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 69

60 SCRIPT
AMMINISTRATIVI
Impostare l’expiration date su un gruppo di utenti per Windows

utenti che devono essere modificati e per ognuno imposta la


data indicata nella variabile ExpireDate. Il file ElencoDN.txt è
formato da righe simili a:

CN=Pippo1,CN=Users,DC=Mydomain,DC=it
CN=Pippo2,CN=Users,DC=Mydomain,DC=it

Option Explicit

Dim FSO ' Oggetto File System Object


Dim LeggiFile ' File di input contenente i DN degli utenti
Dim LogFile ' File di log
Dim CurrentUserDN ' Distinguished Name corrente
Dim ExpireDate ' Data per l'expire
Dim objUser ' Oggetto ADSI (Utente)

' Imposta la data di expire


ExpireDate = "31/12/2006"

' Preleva l'elenco dei server su cui effettuare il controllo


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoDN.txt")

' Controlla se il file di log esiste o occorre crearlo


If (FSO.FileExists("ReportDNUser.log")) Then
Set LogFile = FSO.OpenTextFile("ReportDNUser.log",8)
Else
Set LogFile = FSO.CreateTextFile("ReportDNUser.Log", True)
End If

' Leggi il file con l'elenco dei Distinguished Name degli utenti
' da modificare
Do While Not LeggiFile.AtEndOfStream

I libri di ioPROGRAMMO/60 script amministrativi per Windows 69


007-014 02/02/07 14:56 Pagina 70

60 SCRIPT
AMMINISTRATIVI
per Windows Verificare se un giorno equivale ad un weekend

CurrentUserDN = LeggiFile.ReadLine

On Error Resume Next


Set objUser = GetObject("LDAP://" & CurrentUserDN)

If Err.Number <> 0 Then


LogFile.WriteLine CurrentUserDN & " ERRORE"
Else
objUser.AccountExpirationDate = ExpireDate
objUser.SetInfo
' Scrivi nel log
LogFile.WriteLine CurrentUserDN & " Expire Date " & ExpireDate
End If

Loop

LogFile.Close
LeggiFile.Close

Set FSO = Nothing


Set LogFile = Nothing
Set LeggiFile = Nothing
Set objUser = Nothing

VERIFICARE SE UN GIORNO
EQUIVALE AD UN WEEKEND
Ecco un comodissimo script che consente di recuperare il gior-
no di una settimana per consentire d’intraprendere le giuste
azioni. Questo script, in particolare, è utile per comprendere ed
apprezzare l’oggetto Dictionary di VBS, utilizzato anche in altri
script ed in questa sede in luogo delle apposite costanti messe

70 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 71

60 SCRIPT
AMMINISTRATIVI
Verificare se un giorno equivale ad un weekend per Windows

a disposizione da VBScript.

Option Explicit

Dim DataDaControllare ' Data da controllare


Dim DictWeek ' Oggetto Dictionary

' Crea la corrispondenza dei giorni della settimana


Set DictWeek = CreateObject("Scripting.Dictionary")

DictWeek.Add "DOMENICA", "1"


DictWeek.Add "LUNEDI", "2"
DictWeek.Add "MARTEDI", "3"
DictWeek.Add "MERCOLEDI", "4"
DictWeek.Add "GIOVEDI", "5"
DictWeek.Add "VENERDI", "6"
DictWeek.Add "SABATO", "7"

' Per controllare la data corrente è sufficiente:


DataDaControllare = now

' Controlla se DataDaControllare corrisponde ad un fine settimana


If Weekday(DataDaControllare) = CInt(DictWeek("SABATO")) Or
Weekday(DataDaControllare) = CInt(DictWeek("DOMENICA")) Then
Msgbox "Fine settimana!",vbOkonly, "Informazione"
Else
Msgbox "Non è un fine settimana!",vbOkonly, "Informazione"
End If

Set DictWeek = Nothing

I libri di ioPROGRAMMO/60 script amministrativi per Windows 71


007-014 02/02/07 14:56 Pagina 72

60 SCRIPT
AMMINISTRATIVI
per Windows Elencare gli utenti di un gruppo locale specificato

ELENCARE GLI UTENTI DI UN


GRUPPO LOCALE SPECIFICATO
Questo problema ossia quello di rilevare gli utenti appartenen-
ti ad un gruppo locale, è certamente un “classico”. In questo
script è stato predisposto anche il parametro GRP che consen-
te di passare al programma il nome del gruppo da controllare.
Queste poche righe di codice sono importanti anche perché vie-
ne mostrato come scandire i parametri passati ad un VBS utiliz-
zando le proprietà ed i metodi dell’oggetto Wscript.
Option Explicit

Dim strComputer ' Computer sul quale operare


Dim Messaggio ' Generico messaggio
Dim Gruppo ' Gruppo su cui operare
Dim Account ' Generico membro del gruppo
Dim LocalGroup ' Oggetto GROUP

' Lanciare lo script con il parametro /GRP:<Nome del gruppo>


' Per default viene impostato Administrators

strComputer = "."
Gruppo = "Administrators"

' Controlla se è stato specificato il gruppo


If Wscript.Arguments.Named.Exists("GRP") Then
Gruppo = Wscript.Arguments.Named("GRP")
End If

Set LocalGroup = GetObject("WinNT://" & strComputer & "/" &


Gruppo & ",group")

Messaggio = "Elenco dei membri del gruppo " & Gruppo & vbCrlf &
vbCrlf

72 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 73

60 SCRIPT
AMMINISTRATIVI
Leggere una chiave del Registry sul sistema locale per Windows

' Crea la stringa con l'elenco degli account locali


For Each Account In LocalGroup.Members
Messaggio = Messaggio & Account.Name & vbcrlf
Next

' Mostra a video l'elenco degli amministratori locali


Messaggiobox Messaggio

Set LocalGroup = Nothing

LEGGERE UNA CHIAVE DEL


REGISTRY SUL SISTEMA LOCALE
Ecco un semplice script per leggere dati dal Registry. In partico-
lare, in questo esempio, abbiamo preso in considerazione due chia-
vi del Registry che consentono di rilevare la versione dell’anti-
virus McAfee e quella del DAT. In quest’esempio il tipo di chia-
ve da leggere, in entrambi i casi, è REG_SZ e, per questa ragio-
ne, è stato sufficiente il metodo RegRead() dell’oggetto Wscript.Shell.
In casi più particolari, come avremo modo di verificare in segui-
to, quest’oggetto non può tornarci utile e dovremo ricorrere,
ancora una volta, a WMI.

Option Explicit

Dim WSHShell ' Oggetto WShell


Dim RegKey ' Chiave del Registry
Dim VirDef ' Virus Definition
Dim EngineVer ' Engine Version

' Imposta la chiave per leggere le informazioni su McAfee


Set WSHShell = CreateObject("WScript.Shell")

I libri di ioPROGRAMMO/60 script amministrativi per Windows 73


007-014 02/02/07 14:56 Pagina 74

60 SCRIPT
AMMINISTRATIVI
per Windows Leggere una chiave del Registry su un sistema remoto

RegKey = "HKEY_LOCAL_MACHINE\SOFTWARE\Network
Associates\TVD\Shared Components\VirusScan Engine\4.0.xx\"

' Leggi le informazioni che trovi nel Registry

VirDef = WSHShell.RegRead(RegKey & "szVirDefVer")


EngineVer = WSHShell.RegRead(RegKey & "szEngineVer")

Wscript.Echo "Engine Version: " & vbTab & EngineVer & vbCrlf &
"Virus Definition: " & vbTab &VirDef

Set WSHShell = Nothing

LEGGERE UNA CHIAVE DEL


REGISTRY SU UN SISTEMA
REMOTO
Questo script è simile al precedente per quanto riguarda l’o-
biettivo da raggiungere, ma presenta due particolarità: legge il
Registry su più macchine remote e genera un log con le informa-
zioni ottenute. In particolare, per la lettura delle chiavi szVir-
DefVer e szEngineVer si serve della classe WMI StdRegProv che
vedremo essere più potente dell’analogo oggetto visto nello
script precedente.

Option Explicit

Dim WSHShell ' Oggetto WShell


Dim RegKey ' Chiave del Registry
Dim VirDef ' Virus definition
Dim EngineVer ' Engine Version
Dim FSO ' Oggetto FSO
Dim LeggiFile ' Puntatore al file contenente l'elenco dei server

74 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 75

60 SCRIPT
AMMINISTRATIVI
Leggere una chiave del Registry su un sistema remoto per Windows

Dim LogFile ' Puntatore al file di log


Dim ServerCorrente ' Generico server
Dim rRegistry ' Oggetto WMI
Dim strKeyPath ' Percorso del Registry ove reperire le info

Const HKEY_CLASSES_ROOT = &H80000000 ' Non


usata qui
Const HKEY_CURRENT_USER = &H80000001 ' Non
usata qui
Const HKEY_LOCAL_MACHINE = &H80000002
Const HKEY_USERS = &H80000003 ' Non usata qui
Const HKEY_CURRENT_CONFIG = &H80000005 ' Non usata qui

VirDef = "szVirDefVer"
EngineVer = "szEngineVer"

' Preleva l'elenco dei server su cui effettuare il controllo


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Controlla se il file di log esiste o occorre crearlo


If (FSO.FileExists("ReportMcAfee.csv")) Then
Set LogFile = FSO.OpenTextFile("ReportMcAfee.csv",8)
Else
Set LogFile = FSO.CreateTextFile("ReportMcAfee.csv", True)
End If

' CHIAVE DA LEGGERE:


' HKEY_LOCAL_MACHINE\SOFTWARE\Network Associates\TVD\Shared
Components\VirusScan Engine\4.0.xx\
' ->szVirDefVer
' ->szEngineVer

I libri di ioPROGRAMMO/60 script amministrativi per Windows 75


007-014 02/02/07 14:56 Pagina 76

60 SCRIPT
AMMINISTRATIVI
per Windows Leggere una chiave del Registry su un sistema remoto

' Leggi il file con l'elenco dei server e, per ognuno, leggi
' le informazioni che trovi nel Registry

LogFile.WriteLine "SERVER;VIRUS DEFINITION; ENGINE VERSION"


Do While Not LeggiFile.AtEndOfStream

ServerCorrente = LeggiFile.ReadLine
Set rRegistry = GetObject("winmgmts:{impersonationLevel
=impersonate}//" & _
ServerCorrente & "/root/default:StdRegProv")

strKeyPath = "SOFTWARE\Network Associates\TVD\Shared


Components\VirusScan Engine\4.0.xx"

rRegistry.GetStringValue
HKEY_LOCAL_MACHINE,strKeyPath,VirDef,VirDef
rRegistry.GetStringValue
HKEY_LOCAL_MACHINE,strKeyPath,EngineVer,EngineVer

LogFile.WriteLine ServerCorrente & ";" & VirDef & ";" & EngineVer
& ";"

Loop

LogFile.Close
LeggiFile.Close

Set WSHShell = Nothing


Set FSO = Nothing
Set LeggiFile = Nothing
Set LogFile = Nothing
Set rRegistry = Nothing

76 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 77

60 SCRIPT
AMMINISTRATIVI
Disabilitare le Administrative Shares per Windows

DISABILITARE
LE ADMINISTRATIVE SHARES
Le share amministrative, com’è facile intuire, rappresentano del-
le condivisioni nascoste che vengono precaricate all’avvio di un
sistema proprio per consentire di effettuare operazioni ammini-
strative sulle macchine. In realtà, però, questo genere di condi-
visioni, in alcuni ambienti, sono inutili e, comunque, costitui-
scono per certi versi un punto debole della sicurezza del siste-
ma stesso. Comunque sia, per evitare che vengano ripristinate
ad ogni riavvio del sistema, possiamo disabilitarle intervenendo
direttamente sul registro di sistema. La procedura varia legger-
mente a seconda se la macchina è un server o una workstation.

Option Explicit
Dim strComputer ' Computer sul quale operare
Dim objWMIService ' Oggetto WMI
Dim colOperatingSystems ' Collection d'informazioni
sul sistema operativo
Dim objOperatingSystem ' Item della
collection colOperatingSystem
Dim WshShell ' Oggetto WShell
Dim strAdminShare ' Chiave del Registry con le impostazioni
delle share amministrative
Dim SystemType ' Identifica il tipo di sistema

Const HKEY_LOCAL_MACHINE = &H80000002

strComputer = "."

Set objWMIService =
GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
strComputer & "\root\cimv2")
Set colOperatingSystems = objWMIService.ExecQuery("Select

I libri di ioPROGRAMMO/60 script amministrativi per Windows 77


007-014 02/02/07 14:56 Pagina 78

60 SCRIPT
AMMINISTRATIVI
per Windows Disabilitare le Administrative Shares

ProductType from Win32_OperatingSystem")

For Each objOperatingSystem In colOperatingSystems

SystemType = objOperatingSystem.ProductType
Next

' Per poter disabilitare le Administrative share occorre impostare


opportunamente una
' chiave del Registry in questo modo:
' - SERVER -
'
' Hive: HKEY_LOCAL_MACHINE
' Key: SYSTEM\CurrentControlSet\Services\LanManServer\Parameters
' Name: AutoShareServer
' Data Type: REG_DWORD
' Value: 0
'
' - WORKSTATION -
'
' Hive: HKEY_LOCAL_MACHINE
' Key: SYSTEM\CurrentControlSet\Services\LanManServer\Parameters
' Name: AutoShareWks
' Data Type: REG_DWORD
' Value: 0

Set WshShell = Wscript.CreateObject("Wscript.Shell")

' Determina se il sistema è un SERVER o una WORKSTATION


Select Case SystemType
Case 1:
' Il sistema è una WORKSTATION

78 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 79

60 SCRIPT
AMMINISTRATIVI
Disabilitare le Administrative Shares per Windows

On Error Resume Next


' Leggi le impostazioni dal Registry
strAdminShare =
WshShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Services\" _
&
"LanManServer\Parameters\AutoShareWks")

If Err.Number <> 0 Or strAdminShare = "1" Then


' La chiave non esiste.... Tento di risolvere creandola
/impostandola
Err.clear
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\Services\" _
&
"LanManServer\Parameters\AutoShareWks",0, "REG_DWORD"
End If

Case Else
' Il sistema operativo è un SERVER

On Error Resume Next


' Leggi le impostazioni dal Registry
strAdminShare =
WshShell.RegRead("HKLM\SYSTEM\CurrentControlSet\Services\" _
&
"LanManServer\Parameters\AutoShareServer")

If Err.Number <> 0 Or strAdminShare = "1" Then


' La chiave non esiste.... Tento di risolvere creandola
/impostandola
Err.clear
WshShell.RegWrite
"HKLM\SYSTEM\CurrentControlSet\Services\" _

I libri di ioPROGRAMMO/60 script amministrativi per Windows 79


007-014 02/02/07 14:56 Pagina 80

60 SCRIPT
AMMINISTRATIVI
per Windows Leggere un file INI

&
"LanManServer\Parameters\AutoShareServer",0, "REG_DWORD"
End If

End Select

Set WshShell = Nothing


Set objWMIService = Nothing
Set colOperatingSystems = Nothing
Set objOperatingSystem = Nothing

LEGGERE UN FILE INI


I file .INI non credo abbiamo bisogno di particolari spiegazioni.
Erano molto utilizzati con versioni precedenti di Windows, ma tutt’o-
ra, in alcune realtà, sono ancora presenti. In ogni caso, lo script
che segue permette di leggere i valori di un qualunque para-
metro di un file .INI e, sebbene possa sembrare superfluo, la
tecnica utilizzata potrebbe tornare utile in altre occasioni.

Option Explicit

Dim FSO ' Oggetto File System Object


Dim Sezione ' Sezione del file .INI
Dim Parametro ' Parametro relativo alla sezione considerata
Dim ValParametro ' Valore del parametro letto
Dim Riga ' Generica riga del file .INI
Dim SezioneTrovata ' Flag per determinare se la sezione
richiesta è stata trovata
Dim ParamTrovato ' Flag per determinare se il parametro
richiesto è stata trovato
Dim LeggiFile ' Puntatore al file .INI

80 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 81

60 SCRIPT
AMMINISTRATIVI
Leggere un file INI per Windows

Sezione = "SEZIONE A"


Parametro = "Param1"
SezioneTrovata = 0
ParamTrovato = 0

' Apriamo il file da leggere


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("Configurazione.ini")

Parametro = Parametro & "="

Do While (Not LeggiFile.AtEndOfStream) And ParamTrovato = 0

Riga = LeggiFile.ReadLine
' Wscript.Echo Riga
If SezioneTrovata = 1 Then
' La sezione è stata trovata. Cerchiamo il parametro
' Fermati se incontri prima un'altra sezione. Questo
' significherebbe che il parametro non esiste.
If MID(Riga,1,1) = "[" Then
Wscript.Echo "Il parametro selezionato non esiste!"
Wscript.quit
End If

' Cerca all'inizio della riga corrente


If Mid(Riga,1,Len(Parametro)) = Parametro Then
ValParametro = Mid(Riga,Len(Parametro)+1,Len(Riga)-
Len(Parametro))
Wscript.Echo "Il parametro " & Parametro & " ha valore
" &ValParametro
ParamTrovato = 1
End If

I libri di ioPROGRAMMO/60 script amministrativi per Windows 81


007-014 02/02/07 14:56 Pagina 82

60 SCRIPT
AMMINISTRATIVI
per Windows Scrivere in un file INI

End If

' Controlla se la sezione l'abbiamo già trovata


If SezioneTrovata = 0 Then
If Riga = "[" & Sezione & "]" Then
' Ho trovato la sezione. Cerchiamo ora il parametro
SezioneTrovata = 1
End If
End If
Loop

' Visualizza un messaggio di errore nel caso di esito negativo


If SezioneTrovata = 0 Then
Wscript.Echo "Ricerca sezione fallita!"
End If

If ParamTrovato = 0 Then
Wscript.Echo "Ricerca parametro fallita!"
End If

LeggiFile.Close

Set FSO = Nothing


Set LeggiFile = Nothing

SCRIVERE IN UN FILE INI


Nello script precedente abbiamo visto come leggere un qualun-
que file .INI. In questo script viene mostrato come modificarne
uno o, meglio, come modificare il valore di un parametro. Mal-
grado i file .INI siano meno utilizzati di una volta, questo script
offre a tutti un valido iuto per comprendere quale possa essere
la tecnica per modificare un qualunque file da VBS.

82 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 83

60 SCRIPT
AMMINISTRATIVI
Scrivere in un file INI per Windows

Option Explicit

Dim FSO ' Oggetto File System Object


Dim Sezione ' Sezione da modificare
Dim Parametro ' Parametro da modificare
Dim Riga ' Riga corrente
Dim NuovoValore ' Nuovo valore da impostare
Dim FileINI ' Stringa che contiene il percorso al file INI
Dim FileINI2 ' Stringa che contiene il percorso al nuovo file
INI
' (quello che riporterà le modifiche)
Dim ParamTrovato ' Flag che indica che il parametro è stato
trovato
Dim SezioneTrovata ' Flag che indica che la sezione è stata
trovato
Dim LeggiFile ' Puntatore al file .INI
Dim NewFileINI ' Puntatore al nuovo file .INI

Sezione = "SEZIONE B"


Parametro = "Param1"
NuovoValore = "NEW_VAL2"

SezioneTrovata = 0
ParamTrovato = 0

FileINI = "Configurazione.ini"
FileINI2 = "Configurazione.new"

' Apriamo il file da leggere


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile(FileINI)

I libri di ioPROGRAMMO/60 script amministrativi per Windows 83


007-014 02/02/07 14:56 Pagina 84

60 SCRIPT
AMMINISTRATIVI
per Windows Scrivere in un file INI

' Crea una copia di backup del file INI originale


FSO.CopyFile FileINI, "Configurazione.ori"

' Crea un nuovo file .INI che conterrà la modifica


' Se ne trovi già uno, eliminalo
If (FSO.FileExists(FileINI2)) Then
FSO.DeleteFile FileINI2
End If

Set NewFileINI = FSO.CreateTextFile(FileINI2,True)

Parametro = Parametro & "="

' Cerchiamo il parametro da modificare


Do While (Not LeggiFile.AtEndOfStream)

Riga = LeggiFile.ReadLine

If SezioneTrovata = 1 And ParamTrovato = 0 Then


' La sezione è stata trovata. Cerchiamo il parametro
' Fermati se incontri prima un'altra sezione. Questo
' significherebbe che il parametro non esiste.

If MID(Riga,1,1) = "[" Then


Wscript.Echo "Il parametro selezionato non esiste!"
Wscript.quit
End If

' Cerca all'inizio della riga corrente


If Mid(Riga,1,Len(Parametro)) = Parametro And ParamTrovato
= 0 Then
ParamTrovato = 1
' Imposta il nuovo valore

84 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 85

60 SCRIPT
AMMINISTRATIVI
Scrivere in un file INI per Windows

Riga = Parametro & NuovoValore


End If

End If

' Controlla se la sezione l'abbiamo già trovata


If SezioneTrovata = 0 Then
If Riga = "[" & Sezione & "]" Then
' Ho trovato la sezione. Cerchiamo ora il parametro
SezioneTrovata = 1
End If

End If
' Scrivi la riga nel nuovo file
NewFileINI.WriteLine Riga

Loop

' Visualizza il messaggio nel caso di esito negativo


If SezioneTrovata = 0 Then
Wscript.Echo "Ricerca sezione fallita!"
Wscript.Quit
End If

' Adesso elimina il vecchio file INI e rinomina il nuovo


Set LeggiFile = Nothing

FSO.DeleteFile FileINI
Set newFileINI = Nothing

FSO.MoveFile FileINI2, FileINI


LeggiFile.Close

I libri di ioPROGRAMMO/60 script amministrativi per Windows 85


007-014 02/02/07 14:56 Pagina 86

60 SCRIPT
AMMINISTRATIVI
per Windows Ricercare e disinstallare un programma

Set FSO = Nothing


Set LeggiFile = Nothing

RICERCARE E DISINSTALLARE
UN PROGRAMMA
Spesso può essere necessario rimuovere un determinato softwa-
re che si è scoperti essere stato installato “clandestinamente”.
Lo script necessita della stringa precisa del programma incrimi-
nato, ottenuta attraverso l’utilizzo della classe WMI Win32_Pro-
duct. Attraverso un’opportuna query WMI su questa classe e
mediante il metodo Uninstall(), il programma può essere disni-
stallato dal sistema.

Option Explicit

Dim strComputer ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim colSoftware ' Collection dei software installati
Dim objSoftware ' Generico item della collection colSoftware
Dim NomeProgramma ' Nome del programma da disinstallare

strComputer = "."
NomeProgramma = "<Inserire qui la stringa che identifica
il software>"

' Rileva tutti i software installati che corrispondono a quello richiesto


Set objWMIService =
GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
strComputer & "\root\cimv2")

Set colSoftware = objWMIService.ExecQuery("Select * FROM


Win32_Product WHERE " _

86 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 87

60 SCRIPT
AMMINISTRATIVI
Comparare due file per Windows

& "Name = '" & NomeProgramma & "'")

' Controlla se il programma esiste. Se esiste, allora disinstallalo


If colSoftware.Count = 0 Then
WScript.Echo "Il programma indicato non è stato rilevato."
Else
' Disinstalla il programma
For Each objSoftware In colSoftware
objSoftware.Uninstall()
Next

' Verifica che il programma sia stato realmente eliminato


Set colSoftware = objWMIService.ExecQuery("Select * FROM
Win32_Product WHERE " _
& "Name = '" & NomeProgramma &
"'")

' Invia un messaggio


If colSoftware.Count = 0 Then Wscript.Echo "Il programma è
stato rimosso"
End If

Set objWMIService = Nothing


Set colSoftware = Nothing
Set objSoftware = Nothing

COMPARARE DUE FILE


Ecco un semplice script che consente di comparare due file. Es-
so, in realtà, sfrutta un tool esterno offerto da Windows e deno-
minato FC (File Compare). Questo codice, come alcuni altri pre-
senti nel libro, offrono un valido spunto per comprendere come
possa essere letto l’output di un comando esterno avviato da uno

I libri di ioPROGRAMMO/60 script amministrativi per Windows 87


007-014 02/02/07 14:56 Pagina 88

60 SCRIPT
AMMINISTRATIVI
per Windows Comparare due file

script VBS e comportarsi di conseguenza. L’unica, forse, pecca di


tutto questo meccanismo è che occorre conoscere a priori il ti-
po di output che il tool utilizzato produrrà. Nell’esempio, infat-
ti, si è tenuto conto che lo script venga avviato su una macchi-
na Windows XP ITA e che di conseguenza il messaggio ritorna-
to dal comando FC nel caso i due file di input siano uguali, con-
tenga la stringa “nessuna differenza riscontrata”.
Malgrado ciò possa sembrare una limitazione, si deve tener con-
to che in realtà medie il sistema operativo installato è, al 90%,
lo stesso.

Option Explicit

Dim FileA ' Primo file da comparare


Dim FileB ' Secondo file da comparare
Dim OutCompare ' Output del comando FC
Dim objWshShell ' Oggetto WShell
Dim cmdToolCompare' Comando da avviare per la comparazione
Dim StringaDiConferma ' Stringa di conferma del tool FC

FileA = "File1.txt"
FileB = "File2.txt"

StringaDiConferma = "nessuna differenza riscontrata"

Set objWshShell = CreateObject("WScript.Shell")

' Imposta il comando da lanciare


cmdToolCompare = "fc " & FileA & " " & FileB
OutCompare = objWshShell.Exec(cmdToolCompare).StdOut.ReadAll()

' Se la stringa di conferma esiste, allora i file sono uguali


' In caso contrario, verranno mostrate le differenze

88 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 89

60 SCRIPT
AMMINISTRATIVI
Ricercare una stringa all’interno di una cartella per Windows

If Instr(OutCompare, StringaDiConferma) <> 0 Then


Msgbox "OK. I fle sono uguali"
Else
Msgbox "NOT OK. I file non sono uguali"
End If

Set objWshShell = Nothing

RICERCARE UNA STRINGA


ALL’INTERNO DI UNA CARTELLA
Come lo script precedente, ecco un altro esempio che mostra
come sfruttare la potenza di tool esterni ed il linguaggio VBS.

Option Explicit

Dim colFiles ' Gruppo di file su cui operare


Dim StringaDaCercare ' Stringa da cercare
Dim Folder ' Cartella all'interno della quale cercare
Dim OutFindstr ' Output del comando FC
Dim objWshShell ' Oggetto WShell
Dim cmdToolCompare' Comando da avviare per la comparazione
Dim StringaDiConferma ' Stringa di conferma del tool FC
Dim FSO ' Oggetto File System Object
Dim LogFile ' Puntatore al file che conterrà i risultati
Dim Occorrenze ' Flag che indica se è stato trovato almeno un
file
' contenente la stringa indicata
Dim FileCorrente ' Generico file che contiene la stringa da cercare

Folder = "C:\Temp"
colFiles = "*.log"
StringaDaCercare = "LIPPO"

I libri di ioPROGRAMMO/60 script amministrativi per Windows 89


007-014 02/02/07 14:56 Pagina 90

60 SCRIPT
AMMINISTRATIVI
per Windows Ricercare una stringa all’interno di una cartella

Occorrenze = 1

Set objWshShell = CreateObject( "WScript.Shell" )

' Imposta il comando da lanciare per la ricerca


' Il parametro /M stampa solo il nome file, comprensivo
' di path, non appena viene trovata la prima corrispondenza
cmdToolCompare = "FINDSTR /M " & StringaDaCercare & " " &
Folder & "\" & colFiles
OutFindstr = objWshShell.Exec(cmdToolCompare).StdOut.ReadAll()

' Se non è stato trovato nulla...


If Len(OutFindstr) = 0 Then
Occorrenze = 0
Msgbox "Nessuna occorrenza trovata"
End If

If Occorrenze = 1 Then
' Adesso creati un file temporaneo per i risultati
Set FSO = CreateObject("Scripting.FileSystemObject")

' Controlliamo l'esistenza del file di log


If (FSO.FileExists("CheckString.log")) Then
Set LogFile = FSO.OpenTextFile("CheckString.log",8)
Else
Set LogFile = FSO.CreateTextFile("CheckString.Log", True)
End If

' Scriviamo il contenuto dell'output del comando


' di ricerca nel file di log per analizzarlo in
' seguito.
LogFile.WriteLine OutFindstr

90 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 91

60 SCRIPT
AMMINISTRATIVI
Informazioni sugli attributi di un file per Windows

' Impostiamo la modalità di lettura


Set LogFile = FSO.OpenTextFile("CheckString.log")

' Leggi il file di output


Do While Not LogFile.AtEndOfStream
FileCorrente = LogFile.ReadLine
' Ora hai il nome di un file che contiene la stringa indicata.
' Fa qualcosa...
' ...
Loop
End If

LogFile.Close

Set objWshShell = Nothing


Set FSO = Nothing
Set LogFile = Nothing

INFORMAZIONI SUGLI
ATTRIBUTI DI UN FILE
Questo è un semplicissimo script al quale viene passato il nome
di un file, completo di path e viene visualizzato a video l’elen-
co degli attributi. Lo script controlla sia l’esistenza del file sia
la possibilità che il parametro passato corrisponda ad una direc-
tory.

Option Explicit

' ----------------------------------------------------------------------------------
' ATTRIBUTI:
'

I libri di ioPROGRAMMO/60 script amministrativi per Windows 91


007-014 02/02/07 14:56 Pagina 92

60 SCRIPT
AMMINISTRATIVI
per Windows Informazioni sugli attributi di un file

' Normal 0 Normal file. No Attributes are Set.


' ReadOnly 1 Read-only file. Attribute Is read/write.
' Hidden 2 Hidden file. Attribute Is read/write.
' System 4 System file. Attribute Is read/write.
' Volume 8 Disk drive volume label. Attribute Is read-only.
' Directory 16 Folder Or directory. Attribute Is read-only.
' Archive 32 File has changed since last backup. Attribute is
read/write.
' Alias 64 Link Or shortcut. Attribute Is read-only.
' Compressed 2048 Compressed file. Attribute
Is read-only.
' ----------------------------------------------------------------------------------
' Lanciare lo script con il parametro /F seguito dal nome del file.
' Ad esempio: cscript <Nome script> /F:<Nome file>
' ----------------------------------------------------------------------------------

Dim FSO ' Oggetto File System Object


Dim ElencoAttributi ' Attributi del file
Dim objFile ' Oggetto File sul quale operare
Dim FileName ' Nome del file

' Controlla se è stato passato il file


If WScript.Arguments.Named("F") = "" Then
Wscript.Echo "E' necessario specificare un file come parametro"
WScript.Quit
Else
FileName = WScript.Arguments.Named("F")
End If

Set FSO = CreateObject("Scripting.FileSystemObject")

' Controlla se il file passato esiste


If Not FSO.FileExists(FileName) Then

92 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 93

60 SCRIPT
AMMINISTRATIVI
Informazioni sugli attributi di un file per Windows

' Controlla che se per caso è una directory


If Not(FSO.FolderExists(FileName)) Then
WScript.Echo "Il parametro passato non è nè un file nè una
directory"
WScript.Quit
Else
Set objFile = FSO.GetFolder(FileName)
End If
Else
Set objFile = FSO.GetFile(FileName)
End If

' Mostra l'elenco degli attributi


ElencaAttributi objFile

Set FSO = Nothing


Set objFile = Nothing

Sub ElencaAttributi(objFile2)
' Attributi del file. Alcuni sono di sola lettura, altri di lettura/
scrittura
' HIDDEN
If (objFile2.Attributes And 2) Then
ElencoAttributi = ElencoAttributi & "H"
End If
' READ ONLY
If (objFile2.Attributes And 1) Then
ElencoAttributi = ElencoAttributi & "R"
End If
' SYSTEM
If (objFile2.Attributes And 4) Then
ElencoAttributi = ElencoAttributi & "S"
End If

I libri di ioPROGRAMMO/60 script amministrativi per Windows 93


007-014 02/02/07 14:56 Pagina 94

60 SCRIPT
AMMINISTRATIVI
per Windows Avviare un’installazione remota

' VOLUME
If (objFile2.Attributes And 8) Then
ElencoAttributi = ElencoAttributi & "V"
End If
' DIRECTORY
If (objFile2.Attributes And 16) Then
ElencoAttributi = ElencoAttributi & "D"
End If
' ARCHIVE
If (objFile2.Attributes And 32) Then
ElencoAttributi = ElencoAttributi & "A"
End If
' ALIAS
If (objFile2.Attributes And 64) Then
ElencoAttributi = ElencoAttributi & "L"
End If
' COMPRESSED
If (objFile2.Attributes And 2048) Then
ElencoAttributi = ElencoAttributi & "C"
End If

ElencoAttributi = "Attributi: " & ElencoAttributi

Msgbox ElencoAttributi

End Sub

AVVIARE
UN’INSTALLAZIONE REMOTA
Un’esigenza ricorrente in un ambiente di rete è quella d’instal-

94 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 95

60 SCRIPT
AMMINISTRATIVI
Avviare un’installazione remota per Windows

lare pacchetti relativi a hotfix e patch che la Microsoft periodi-


camente rilascia. Se non abbiamo a disposizione server predispo-
sti a quest’operazione o, semplicemente vogliamo occuparcene
noi, ecco un esempio di come possiamo avviare un’installazio-
ne remota di un applicativo contenuto all’interno di una cartel-
la del server. Malgrado possa sembra uno script “scontato” si ten-
ga presente che per poter avviare un eseguibile che agisca su di
un sistema remoto, non possiamo utilizzare i metodi e gli ogget-
ti visti sinora, ma occorre creare proprio un processo sulla mac-
china remota. Questa sottigliezza è importantissima perché se
provassimo ad eseguire metodi Exec() o Run() di oggetti Shell,
riscontreremmo risultati “inaspettati”.
La creazione di un processo è un procedimento piuttosto sem-
plice e, se sfruttato bene, può dare molte soddisfazioni.

Option Explicit

Dim Utente ' Nome utente per l'accesso al sistema


Dim Password ' Password dell'utente
Dim FSO ' Oggetto File System Object
Dim LeggiFile ' File di input contenente i server a cui
collegarsi
Dim LogFile ' File di log
Dim ServerCorrente ' Server corrente su cui operare
Dim objLocator ' Oggetto WMI
Dim objSvc ' Oggetto WMI
Dim Processo ' Generico processo
Dim intProcessID ' ID del nuovo processo creato
Dim Programma ' Stringa con il path del programma da avviare
Dim Result ' Risultato della creazione del processo

' Imposta i dati relativi alle credenziali da utilizzare


Utente = "MyDomain\flippo"

I libri di ioPROGRAMMO/60 script amministrativi per Windows 95


007-014 02/02/07 14:56 Pagina 96

60 SCRIPT
AMMINISTRATIVI
per Windows Avviare un’installazione remota

Password = "MyPassword"

' Imposta la stringa relativa al programma da installare


Programma = "C:\Programmi\MyApp\Setup.exe /silent"

' Preleva l'elenco dei server su cui effettuare il controllo


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Controlla se il file di log esiste o occorre crearlo


If (FSO.FileExists("CheckInstall.log")) Then
Set LogFile = FSO.OpenTextFile("CheckInstall.log",8)
Else
Set LogFile = FSO.CreateTextFile("CheckInstall.Log", True)
End If

LogFile.WriteLine "SERVER;RESULT"

' Leggi il file con l'elenco dei server e, per ognuno avvia
' l'installazione del programma
Do While Not LeggiFile.AtEndOfStream

ServerCorrente = LeggiFile.ReadLine

On Error Resume Next

' Connettiti al server remoto e avvia il programma


Set objLocator = CreateObject("WbemScripting.SwbemLocator")
Set objSvc = objLocator.ConnectServer(ServerCorrente,
"root\cimv2", Utente, Password)

Set Processo = objSvc.Get("Win32_Process")


Result = Processo.Create(Programma, Null, Null, intProcessID)

96 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 97

60 SCRIPT
AMMINISTRATIVI
Rinominare tutti i file di una cartella per Windows

If Result = 0 Then
LogFile.WriteLine ServerCorrente & ";OK"
Else
LogFile.WriteLine ServerCorrente & ";ERRORE"
End If

Loop

LeggiFile.Close
LogFile.Close

Set FSO = Nothing


Set LeggiFile = Nothing
Set LogFile = Nothing
Set objLocator = Nothing
Set objSvc = Nothing
Set Processo = Nothing

RINOMINARE TUTTI
I FILE DI UNA CARTELLA
Come fa intuire il nome stesso, questo script permette di rino-
minare tutti i file di un certo tipo contenuti all’interno di una
certa cartella.

Option Explicit

Dim FSO ' Oggetto File System Object


Dim SourceFolder ' Directory sorgente
Dim colFiles ' Collection di file
Dim NumberSuffix ' Numero iniziale da impostare come
suffisso

I libri di ioPROGRAMMO/60 script amministrativi per Windows 97


007-014 02/02/07 14:56 Pagina 98

60 SCRIPT
AMMINISTRATIVI
per Windows Rinominare tutti i file di una cartella

Dim FileExt ' Estensione dei file


Dim objFile ' Oggetto "file"
Dim FilePrefix ' Prefisso dei nuovi file
Dim NewFileName ' Nuovo nome del file

' Definisci la cartella sulla quale agire


SourceFolder = "E:\"

' Definisci il prefisso dei file


FilePrefix = "Foto_"

' Definisci il numero da cui cominciare


NumberSuffix = 3

' Definisci l'estensione dei file sui quali operare


FileExt = "txt"

' Controlla se la cartella passata come parametro esiste...


Set FSO = CreateObject("Scripting.FileSystemObject")

If FSO.FolderExists(SourceFolder) Then
Set colFiles = FSO.GetFolder(SourceFolder)
Else
Wscript.Echo "La cartella specificata non esiste"
Wscript.Quit
End If

' Comincia a rinominare i file


For Each objFile In colFiles.Files
If FSO.GetExtensionName(objFile) = FileExt Then
' Fa attenzione ai file che si trovano sulla root delle partizioni
' come C:\, D:\, ecc... In tal caso non aggiungere il '\'.
If Right(objFile.ParentFolder,1) <> "\" Then

98 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 99

60 SCRIPT
AMMINISTRATIVI
Rinominare/Spostare una cartella su più server per Windows

NewFileName = objFile.ParentFolder & "\" & FilePrefix &


NumberSuffix & FileExt
Else
NewFileName = objFile.ParentFolder & FilePrefix &
NumberSuffix & FileExt
End If

FSO.MoveFile objFile.Path, NewFileName


NumberSUffix = NumberSuffix + 1
End If
Next

Set FSO = Nothing


Set objFile = Nothing

RINOMINARE/SPOSTARE
UNA CARTELLA SU PIÙ SERVER
Questo script sposta semplicemente una cartella sorgente in un
altro punto del disco ed effettua l’operazione su diversi server.

Option Explicit

Dim FSO ' Oggetto File System Object


Dim SourceFolder ' Directory sorgente
Dim DestinationFolder ' Directory destinataria
Dim LeggiFile ' Puntatore al file contenente la lista dei server
Dim LogFile ' Puntatore al file di log
Dim ServerCorrente ' Generico server su cui operare
Dim DestinationFolder2 ' Directory destinataria impostata secondo
la convenzione UNC

' Definisci la cartella da copiare

I libri di ioPROGRAMMO/60 script amministrativi per Windows 99


007-014 02/02/07 14:56 Pagina 100

60 SCRIPT
AMMINISTRATIVI
per Windows Rinominare/Spostare una cartella su più server

SourceFolder = "C:\SourceFolder"
DestinationFolder = "C:\DestFolder"

' Leggi il file che contiene l'elenco dei server su cui copiare
' la cartella
Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Sostituisci alla dicitura del tipo C: quella tipo C$


(administrative share)
DestinationFolder = Replace(DestinationFolder,":","$")

' Controlla se è necessario creare il file di log


If (FSO.FileExists("ReportMove.log")) Then
Set LogFile = FSO.OpenTextFile("ReportMove.log",8)
Else
Set LogFile = FSO.CreateTextFile("ReportMove.Log", True)
End If

' Leggi il file contenente i server su cui copiare la cartella


Do While Not LeggiFile.AtEndOfStream
' Determina il server corrente
ServerCorrente = LeggiFile.ReadLine

' Determina la directory di destinazione


DestinationFolder2 = "\\" & ServerCorrente & "\" &
DestinationFolder

On Error Resume Next

' Copia la cartella sul server corrente


FSO.MoveFolder SourceFolder,DestinationFolder2

100 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 101

60 SCRIPT
AMMINISTRATIVI
Abilitare le NULL Session Share per Windows

If Err.Number <> 0 Then


LogFile.WriteLine (ServerCorrente & " Errore! (" & Err.Description
& ")")
Err.clear
Else
LogFile.WriteLine (ServerCorrente & " OK!")
End If
DestinationFolder2 = DestinationFolder
Loop

LeggiFile.Close
LogFile.Close

Set FSO = Nothing


Set LeggiFile = Nothing
Set LogFile = Nothing

ABILITARE LE NULL SESSION


SHARE
Non è questa la sede per affrontare l’argomento delle Null Ses-
sion Share, ma certamente lo script che state per leggere è im-
portante per comprendere come operare sulle chiavi del Registry
del tipo REG_MULTI_SZ utilizzando la classe WMI vista in alcu-
ni script precedenti. Come sottolineato in testa allo script, mag-
giori informazioni riguardo questo argomento le potete ottene-
re direttamente dal sito della Microsoft e precisamente in cor-
rispondenza di http://support.microsoft.com/?scid=kb%3Ben-
us%3B289655&x=19&y=11. Il testo parziale dei passi sugge-
riti da MS è stato inserito come commento all’interno del codi-
ce per consentirne una maggiore e più rapida comprensione.

Option Explicit

I libri di ioPROGRAMMO/60 script amministrativi per Windows 101


007-014 02/02/07 14:56 Pagina 102

60 SCRIPT
AMMINISTRATIVI
per Windows Abilitare le NULL Session Share

' Ecco i passi da eseguire "manualmente" per abilitare le null session


(fonte MS)
' http://support.microsoft.com/?scid=kb%3
Ben-us%3B289655&x=19&y=11
'
' 1. Start Registry Editor (Regedt32.exe).
' 2. Locate the following key in the registry:
'
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanS
erver\Parameters\NullSessionShares
' NOTE: NullSessionShares is a REG_MULTI_SZ value.
' 3. On a new line In the NullSessionShares key, type the name of the
share that you want
' To access with a Null session (For example, Public).
' 4. If the program uses named pipes and requires null session support,
locate the following key in the registry:
'
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\
LanmanServer\Parameters\NullSessionPipes
' NOTE: NullSessionPipes Is a REG_MULTI_SZ value.

' On a new line in the NullSessionPipes key, type the name of the pipe
that you want to access with a null session.
' 5. Locate And click the following key In the registry:
' HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA
' 6. On the Edit menu, click Add Value, and then add the following
registry value:
' Value Name: RestrictAnonymous
' Data Type: REG_DWORD
' Value: 0

Dim strComputer ' Computer sul quale agire

102 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 103

60 SCRIPT
AMMINISTRATIVI
Abilitare le NULL Session Share per Windows

Dim objWMIService ' Oggetto WMI


Dim WshShell ' Oggetto WShell
Dim colNullSessionShare ' Collection di Null Session Shares
Dim colNullSessionShare2() ' Array contenente la col
lection precedente + il nuovo item
Dim strKeyPath ' Percorso nel Registry alle Null Session
Share
Dim oReg ' Oggetto Registry
Dim Cont ' Contatore
Dim ItemNullSessionShare ' Generico item della
collection di null session share

Const HKEY_LOCAL_MACHINE = &H80000002:

strComputer = "."

' Crea gli oggetti per la lettura e scrittura del registry


Set WshShell = Wscript.CreateObject("Wscript.Shell")

strKeyPath =
"System\CurrentControlSet\Services\LanmanServer\Parameters"

Set oReg = GetObject("winmgmts:{impersonationLevel=


impersonate}!\\" & strComputer & "\root\default:StdRegProv")

' Leggi le impostazioni dal Registry (ossia l'elenco delle Null Session
Share)
colNullSessionShare = WshShell.RegRead("HKEY_LOCAL_
MACHINE\System\CurrentControlSet\Services" _
&
"\LanmanServer\Parameters\NullSessionShares")

' Copia ciò che trovato in un nuovo array di appoggio

I libri di ioPROGRAMMO/60 script amministrativi per Windows 103


007-014 02/02/07 14:56 Pagina 104

60 SCRIPT
AMMINISTRATIVI
per Windows Elencare le NULL Session Share

Cont = 0

For Each ItemNullSessionShare In colNullSessionShare


Cont = Cont + 1
Redim Preserve colNullSessionShare2(Cont)
colNullSessionShare2(Cont - 1) = ItemNullSessionShare
Next

' Adesso ridimensiona l'array aggiungendo un altro elemento


Redim Preserve colNullSessionShare2(Cont)

' Inserisci il nome della Null Session Share ed riscrivi la chiave


colNullSessionShare2(Cont) = "SHARE_X$"
oReg.SetMultiStringValue
HKEY_LOCAL_MACHINE,strKeyPath,"NullSessionShares",colNullSessi
onShare2

' PS: Allo stesso modo si può procedere per le Null Session Pipes...

Set WshShell = Nothing


Set objWMIService = Nothing
Set colNullSessionShare = Nothing
Set oReg = Nothing
Set ItemNullSessionShare = Nothing

ELENCARE LE NULL SESSION


SHARE
Dopo aver visto come abilitare le Null Session share in un siste-
ma Windows, vediamo come elencare quelle già presenti. Per
semplicità, non è stata inserita la porzione di codice relativa al-
la seconda chiave del Registry menzionata in testa allo script, ma
il procedimento da seguire è pressocchè lo stesso di quello evi-

104 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 105

60 SCRIPT
AMMINISTRATIVI
Elencare le NULL Session Share per Windows

denziato.

Option Explicit

' Ecco dove sono memorizzate le null session share e le null session
pipes(fonte MS)
' http://support.microsoft.com/?scid=kb%3
Ben-us%3B289655&x=19&y=11
'
' > NULL SESSION SHARE <
'
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanman
Server\Parameters\NullSessionShares
' > NULL SESSION PIPES <
'
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Lanman
Server\Parameters\NullSessionPipes

Dim strComputer ' Computer corrente


Dim objWMIService ' Oggetto WMI
Dim WshShell ' Oggetto Shell
Dim colNullSessionShare ' Collection Null Session Share
Dim colNullSessionPipes ' Collection Null Session Pipes
Dim Cont ' Semplice contatore

Const HKEY_LOCAL_MACHINE = &H80000002

strComputer = "."

Set objWMIService =
GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
strComputer & "\root\cimv2")

I libri di ioPROGRAMMO/60 script amministrativi per Windows 105


007-014 02/02/07 14:56 Pagina 106

60 SCRIPT
AMMINISTRATIVI
per Windows Modificare la password di un utente su più server

Set WshShell = Wscript.CreateObject("Wscript.Shell")

' Leggi le impostazioni dal Registry


' Null Session Share
colNullSessionShare = WshShell.RegRead("HKEY_LOCAL_
MACHINE\System\CurrentControlSet\Services" _
&
"\LanmanServer\Parameters\NullSessionShares")

' Elenca le Null Session Share


For Cont = 0 To Ubound(colNullSessionShare)
Wscript.Echo colNullSessionShare(Cont)
Next

colNullSessionPipes = WshShell.RegRead("HKEY_LOCAL_
MACHINE\System\CurrentControlSet\Services" _
&
"\LanmanServer\Parameters\NullSessionPipes")

' Elenca le Null Session Pipes


For Cont = 0 To Ubound(colNullSessionPipes)
Wscript.Echo colNullSessionPipes(Cont)
Next

Set objWMIService = Nothing


Set WshShell = Nothing

MODIFICARE LA PASSWORD
DI UN UTENTE SU PIÙ SERVER
Questo script consente di modificare la password di un utente
locale presente su più server. Allo stesso modo di quanto visto
in precedenti script, questo preleva il nome del server su cui

106 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 107

60 SCRIPT
AMMINISTRATIVI
Modificare la password di un utente su più server per Windows

operare da un file d’input denominato ElencoServer.txt e per


ciascun sistema rilevato, modifica la password servendosi di AD-
SI e, più precisamente, del provider WinNT.

Option Explicit

Dim Utente ' Utente da modificare


Dim FSO ' Oggetto File System Object
Dim LeggiFile ' File contenente i server su cui operare
Dim LogFile ' File di log
Dim objUser ' Oggetto ADSI "user"
Dim ServerCorrente ' Server corrente su cui operare

' Utente da modificare


Utente = "pippo"

' Preleva l'elenco dei server su cui effettuare il cambio password


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Controlla se il file di log esiste o occorre crearlo


If (FSO.FileExists("CheckCambioPass.log")) Then
Set LogFile = FSO.OpenTextFile("CheckCambioPass.log",8)
Else
Set LogFile = FSO.CreateTextFile("CheckCambioPass.Log", True)
End If

' Leggi il file con l'elenco dei server


Do While Not LeggiFile.AtEndOfStream

ServerCorrente = LeggiFile.ReadLine

On Error Resume Next

I libri di ioPROGRAMMO/60 script amministrativi per Windows 107


007-014 02/02/07 14:56 Pagina 108

60 SCRIPT
AMMINISTRATIVI
per Windows Ottenere l’elenco dei job schedulati

Set objUser = GetObject("WinNT://" & ServerCorrente & "/" &


Utente, user)

If Err <> 0 Then


LogFile.WriteLine ServerCorrente & " Errore! " & Err.Description
Err.Clear
Else
objUser.SetPassword "12345678"
objUser.SetInfo
LogFile.WriteLine ServerCorrente & " OK!"
End If

Loop

Msgbox "Ho terminato…"

LeggiFile.Close
LogFile.Close

Set FSO = Nothing


Set LeggiFile = Nothing
Set LogFile = Nothing
Set objUser = Nothing

OTTENERE L’ELENCO
DEI JOB SCHEDULATI
Questo script elenca tutti i job schedulati su di un sistema sem-
plicemente elencando tutti i file .JOB che si trovano nella cartel-
la %WinDir%\Tasks. La directory d’installazione di Windows
può essere ottenuta in vari modi. Qui è stato sfruttato WMI. Un
altro sistema è utilizzare un’istruzione del tipo WshShell.Expan-

108 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 109

60 SCRIPT
AMMINISTRATIVI
Ottenere l’elenco dei job schedulati per Windows

dEnvironmentStrings("%WINDIR%").

Option Explicit

Dim PathJobSchedulati ' Percorso della cartella relativa ai job


schedulati
Dim strComputer ' Computer sul quale operare
Dim objWMIService ' Oggetto WMI
Dim colItems ' Collection d'informazioni sul computer
Dim WindowsDir ' Percorso installazione Windows
Dim FSO ' Oggetto File System Object
Dim Item ' Generico item collection file .JOB
Dim FolderObject ' Oggetto Folder
Dim colFiles ' Collection dei file .JOB
Dim file ' Generico file della collection colFiles
Dim ListaJob ' Lista dei file relativi ai job schedulati

strComputer = "."

' Identifica la cartella ove è installato Windows


' (questo è uno dei vari metodi possibili).
Set objWMIService = GetObject("winmgmts:\\" & strComputer &
"\root\CIMV2")
Set colItems = objWMIService.ExecQuery("SELECT WindowsDirectory
FROM Win32_OperatingSystem")

' Memorizza la cartella ove è installato Windows


For Each Item In colItems
WindowsDir = Item.WindowsDirectory
Next

' Preleva tutti i files nella directory %WINDIR%\Tasks


PathJobSchedulati = WindowsDir & "\Tasks"

I libri di ioPROGRAMMO/60 script amministrativi per Windows 109


007-014 02/02/07 14:56 Pagina 110

60 SCRIPT
AMMINISTRATIVI
per Windows Ottenere la lista dei processi e dei relativi thread

Set FSO = CreateObject("Scripting.FileSystemObject")


Set FolderObject = FSO.GetFolder(PathJobSchedulati)
Set colFiles= FolderObject.Files

' Dalla collection files controlla se ci sono file .job


If colFiles.count = 0 Then
Wscript.Echo "Non ci sono job schedulati"
Wscript.Quit
End If

For Each file In colFiles


' Se ci sono file .job
If FSO.GetExtensionName(file) = "job" Then
ListaJob = ListaJob & "--> " & file.Name & vbCrlf
End If
Next

Wscript.Echo "Ecco l'elenco dei job" & vbCrlf & vbCrlf & ListaJob

Set colFiles = Nothing


Set FolderObject = Nothing
Set FSO = Nothing
Set objWMIService = Nothing
Set colItems = Nothing

OTTENERE LA LISTA DEI


PROCESSI E DEI RELATIVI
THREAD
Chiunque di noi sa benissimo che ad ogni processo possono es-
sere associati più thread. Ovviamente ocorre un pò di pazienza
per ottenere la lista di queste associazioni, ma servendosi di

110 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 111

60 SCRIPT
AMMINISTRATIVI
Ottenere la lista dei processi e dei relativi thread per Windows

due classi WMI, la Win32_Process e la Win32_Thread, queste infor-


mazioni sono abbastanza semplici da ottenere. Qui, peraltro, è
mostrata ancora una volta, la validità dell’oggetto Dictionary, uti-
lissimo per tener traccia delle informazioni. Senza troppe com-
plicazioni, lo script preleva la lista dei processi attivi mappando
nome e ID del processo attraverso un oggetto Dictionary. Il se-
condo passo è simile. Viene effettuata una query sulla collec-
tion di thread attivi e, sevendosi dell’ID del processo (una pro-
prietà di questi oggetti), è possibile rilevare tramite il Dictio-
nary, la corrispondenza cercata.

Option Explicit

Dim ServerCorrente ' Identifica il server su cui operare


Dim objDict ' Oggetto Dictionary utile per la mappatura della
' corrispondenzaProcesso-Thread
Dim objWMIService ' Oggetto WMI
Dim colProcesses ' Collection dei processi
Dim objProcess ' Singolo processo della collection
Dim ProcessID ' ID del processo
Dim colThreads ' Collection dei Thread
Dim objThread ' Singolo Thread
Dim FSO ' Oggetto File System Object
Dim LeggiFile ' Puntatore al file contenente l'elenco dei server
Dim LogFile ' Puntatore al file di log
Dim NomeProcesso ' Nome del processo

' Preleva l'elenco dei server su cui effettuare il controllo


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Controlla se il file di log esiste o occorre crearlo


If (FSO.FileExists("ReportProcess.log")) Then

I libri di ioPROGRAMMO/60 script amministrativi per Windows 111


007-014 02/02/07 14:56 Pagina 112

60 SCRIPT
AMMINISTRATIVI
per Windows Ottenere la lista dei processi e dei relativi thread

Set LogFile = FSO.OpenTextFile("ReportProcess.log",8)


Else
Set LogFile = FSO.CreateTextFile("ReportProcess.Log", True)
End If

' Crea un oggetto Dictionary


Set objDict = CreateObject("Scripting.Dictionary")

' Leggi il file contenente l'elenco dei server

LogFile.WriteLine "SERVER;PROCESSO;ID PROCESSO;THREAD


HANDLE"

Do While Not LeggiFile.AtEndOfStream

' Azzera l'oggetto Dictionary


objDict.RemoveAll

ServerCorrente = LeggiFile.ReadLine

' Collegati alla macchina e preleva la lista dei processi


Set objWMIService = GetObject("winmgmts:" &
"{impersonationLevel=impersonate}!\\" & ServerCorrente &
"\root\cimv2")
Set colProcesses = objWMIService.ExecQuery ("SELECT ProcessID,
Name FROM Win32_Process")

' Colleziona le informazioni sui processi, memorizzandoli


nell'oggetto Dictionary
For Each objProcess In colProcesses
objDict.Add objProcess.ProcessID, objProcess.Name
Next

112 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 113

60 SCRIPT
AMMINISTRATIVI
Ottenere la lista dei processi e dei relativi thread per Windows

' Preleva la lista di tutti i Thread


Set colThreads = objWMIService.ExecQuery ("SELECT
ProcessHandle, Handle FROM Win32_Thread")

' Per ogni Thread, preleva le informazioni relative al processo


associato
' e, sfruttando l'oggetto Dictionary, mostra i dettagli
For Each objThread In colThreads

' Recupera l'ID del processo associato


ProcessID = CInt(objThread.ProcessHandle)

' Sfruttando l'ID e l'oggetto Dictionary, preleva il nome


del processo
NomeProcesso = objDict.Item(ProcessID)

' Scrivi i risultati


LogFile.WriteLine ServerCorrente & ";" & NomeProcesso & ";"
& ProcessID & ";" & objThread.Handle
Next
Loop

LeggiFile.Close
LogFile.Close

Set objDict = Nothing


Set objWMIService = Nothing
Set colProcesses = Nothing
Set objProcess = Nothing
Set colThreads = Nothing
Set objThread = Nothing
Set FSO = Nothing
Set LeggiFile = Nothing

I libri di ioPROGRAMMO/60 script amministrativi per Windows 113


007-014 02/02/07 14:56 Pagina 114

60 SCRIPT
AMMINISTRATIVI
per Windows Impostare l’IP Address da statico a dinamico

Set LogFile = Nothing

IMPOSTARE L’IP ADDRESS


DA STATICO A DINAMICO
Questo script, molto semplice, imposta l’indirizzo IP di un siste-
ma da statico a dinamico.

Option Explicit

Dim strComputer ' Server sul quale operare


Dim objWMIService ' Oggetto WMI
Dim colNetAdapters ' Collection
Dim objNetAdapter ' Generico item della collection
colNetAdapters
Dim DictErr ' Dictionary Object
Dim RetVal ' Valore di ritorno del metodo EnableDHCP()

' Definisci l’oggetto Dictionary per la mappatura codice errore-


descrizione
Set DictErr = CreateObject("Scripting.Dictionary")

' Inserisci “alcuni” dei possibili msg di errore (sito MS) legati
all’operazione
DictErr.Add "0", "Successful completion, no reboot required."
DictErr.Add "1", "Successful completion, reboot required."
DictErr.Add "64", "Method Not supported On this platform."
DictErr.Add "65", "Unknown failure."
DictErr.Add "74", "Invalid host name."
DictErr.Add "79", "Invalid security parameter."
DictErr.Add "80", "Unable To configure TCP/IP service."
DictErr.Add "81", "Unable To configure DHCP service."
DictErr.Add "82", "Unable To renew DHCP lease."

114 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 115

60 SCRIPT
AMMINISTRATIVI
Ottenere informazioni sulle variabili d’ambiente per Windows

DictErr.Add "83", "Unable To release DHCP lease."


DictErr.Add "91", "Access denied."
DictErr.Add "97", "Interface Not configurable."
DictErr.Add "100", "DHCP Not enabled On the adapter."

strComputer = "."

Set objWMIService =
GetObject("winmgmts:{impersonationLevel=impersonate}!\\" &
strComputer & "\root\cimv2")

Set colNetAdapters = objWMIService.ExecQuery("SELECT * FROM


Win32_NetworkAdapterConfiguration WHERE IPEnabled=TRUE")

If colNetAdapters.Count = 0 Then
Wscript.Echo "Non ci sono Network Adapter da configurare"
Wscript.Quit
End If

For Each objNetAdapter In colNetAdapters


RetVal = objNetAdapter.EnableDHCP()
Msgbox DictErr(Cstr(RetVal)),,"Esito operazione"
Next

Set colNetAdapters = Nothing


Set objWMIService = Nothing
Set objNetAdapter = Nothing
Set DictErr = Nothing

OTTENERE INFORMAZIONI
SULLE VARIABILI D’AMBIENTE
Molti degli script che vengono implementati in un ambiente di

I libri di ioPROGRAMMO/60 script amministrativi per Windows 115


007-014 02/02/07 14:56 Pagina 116

60 SCRIPT
AMMINISTRATIVI
per Windows Ottenere informazioni sulle variabili d’ambiente

produzione necessitano di conoscere particolare parametri co-


me la cartella d’installazione di Windows o quella temporanea.
Oltre ai metodi già visti, ovviamente esiste quello d’interroga-
re, se esiste, l’opportuna variabile d’ambiente. Ecco un piccolo
script che si occupa di raggiungere lo scopo. In ingresso può es-
sergli passato il nome della variabile d’ambiente che si vuol co-
noscere.

Option Explicit

Dim strComputer ' Computer sul quale operare


Dim objWMIService ' Oggetto WMI
Dim colEnvVariables ' Collection delle variabili d'ambiente
Dim VarEnv ' Generica variabile d'ambiente
Dim strQuerySuffix ' Secondo pezzo della query WMI
(che specifica, eventualmente)
' il nome della variabile da controllare

strComputer = "."

' Controlla se viene passato il nome della variabile da cercare


' In caso contrario la lista riguarderà tutte le variabili
' d'ambiente. Per passare allo script la variabile PIPPO, ad es.,
' lanciarlo con /VAR:PIPPO
If Wscript.Arguments.Named.Exists("VAR") Then
strQuerySuffix = "WHERE Name = '" &
Wscript.Arguments.Named("VAR") & "'"
End If

Set objWMIService = GetObject("winmgmts:\\" & strComputer &


"\root\cimv2")
Set colEnvVariables = objWMIService.ExecQuery ("SELECT * FROM
Win32_Environment " & strQuerySuffix)

116 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 117

60 SCRIPT
AMMINISTRATIVI
Svuotare la cartella di Prefetch per Windows

' Per ciascuna istanza trovata mostra i dettagli (variabile d’ambiente,


profilo, ecc.)
' Si osservi che, a seconda del profilo, esiste una variabile d'ambiente
con lo stesso ' nome.
For Each VarEnv In colEnvVariables
WScript.Echo "->" & VarEnv.Name & "=" & VarEnv.VariableValue
WScript.Echo vbTab & vbTab & "PROFILO=" & VarEnv.UserName
WScript.Echo vbTab & vbTab & "SYSTEM=" &
VarEnv.SystemVariable
Next

WScript.Echo vbCrLf & "Elenco completato"

' Distruggi l’oggetto


Set objWMIService = Nothing
Set colEnvVariables = Nothing

SVUOTARE
LA CARTELLA DI PREFETCH
Il prefetching è una tecnica in base alla quale Windows XP “ten-
ta” di aumentare le performance del sistema operativo creando
dei file .PF, all’interno di un’apposita cartella, per velocizzare
l’esecuzione dei programmi. Senza entrare troppo nel dettaglio,
questo meccanismo finisce ben presto con l’occupare spazio di-
sco che dovrebbe essere periodicamente liberato. Ecco un sem-
plicescript che fa questo lavoro. In quest’esempio, come in qual-
che altro, è stata variata la modalità di accesso al sistema, uti-
lizzando per l’appunto, un oggetto WMI istanziato con l’istruzio-
ne CreateObject("WbemScripting.SwbemLocator"). Attraverso
esso, come vedremo, vengono passate le informazioni di auten-
ticazione utili ad accedere alla macchina.

I libri di ioPROGRAMMO/60 script amministrativi per Windows 117


007-014 02/02/07 14:56 Pagina 118

60 SCRIPT
AMMINISTRATIVI
per Windows Svuotare la cartella di Prefetch

Option Explicit

Dim FSO ' Oggetto File System Object


Dim LeggiFile ' Puntatore al file che contiene l'elenco dei
server
Dim LogFile ' Puntatore al file di log
Dim ServerCorrente ' Computer sul quale operare
Dim WindowsDir ' Directory d'installazione di Windows
Dim PrefetchFolder ' Cartella di Prefetch
Dim objWMIService ' Oggetto WMI
Dim colItems ' Collection d'informazioni classe
Win32_OperatingSystem
Dim Item ' Generico item della collection precedente
Dim Utente ' Utente utile per l'autenticazione
Dim Password ' Password dell'utente
Dim objLocator ' Oggetto WMI

Utente = "MyDomain\FLIPPO"
Password = "MyPassword"

' Leggi il file che contiene l'elenco dei server su cui copiare
' la cartella
Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Controlla se è necessario creare il file di log


If (FSO.FileExists("Prefetch.log")) Then
Set LogFile = FSO.OpenTextFile("Prefetch.log",8)
Else
Set LogFile = FSO.CreateTextFile("Prefetch.Log", True)
End If
' Leggi il file contenente i server su cui copiare la cartella
Do While Not LeggiFile.AtEndOfStream

118 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 119

60 SCRIPT
AMMINISTRATIVI
Svuotare la cartella di Prefetch per Windows

' Impostiamo il server su cui operare


ServerCorrente = LeggiFile.ReadLine

' Preleva le informazioni sulla Windows Directory

' Connettiti al server remoto e avvia il programma


Set objLocator = CreateObject("WbemScripting.SwbemLocator")
Set objWMIService = objLocator.ConnectServer(ServerCorrente,
"root\cimv2", Utente, Password)

Set colItems = objWMIService.ExecQuery("SELECT * FROM


Win32_OperatingSystem")

For Each Item In colItems


WindowsDir= Item.WindowsDirectory
Next

' WindowsDir contiene qualcosa del tipo C:\Windows.


' Per costruire la stringa correttamente, sostituiamo C: con C$
WindowsDir = Replace (WindowsDir,":","$")

' Imposta la cartella di Prefetch


PrefetchFolder = "\\" & ServerCorrente & "\" & WindowsDir &
"\Prefetch"

On Error Resume Next

' Punta ora alla cartella Prefetch sul server corrente


FSO.GetFolder(PrefetchFolder)

FSO.DeleteFile PrefetchFolder & "\*.pf", True


If Err.Number <> 0 Then

I libri di ioPROGRAMMO/60 script amministrativi per Windows 119


007-014 02/02/07 14:56 Pagina 120

60 SCRIPT
AMMINISTRATIVI
per Windows Avviare il controllo antivirus su di una cartella

LogFile.WriteLine (ServerCorrente & " Errore! (" & Err.Description


& ")")
Err.clear
Else
LogFile.WriteLine (ServerCorrente & " OK!")
End If

Loop

LeggiFile.Close
LogFile.Close

Set FSO = Nothing


Set LeggiFile = Nothing
Set LogFile = Nothing
Set objWMIService = Nothing
Set objLocator = Nothing
Set colItems = Nothing

AVVIARE IL CONTROLLO
ANTIVIRUS SU DI UNA CARTELLA
Lo script che stiamo per mostrare, assieme ad alcuni che lo se-
guiranno, è molto particolare. Senza entrare troppo nei dettagli,
diciamo che, attraverso l’utilizzo di opportuni oggetti (Shell
Object), possiamo avviare azioni molto particolari su cartelle,
sul cestino, ecc. L’argomento è senza dubbio difficile da spie-
gare in questa sede ed in poche righe. Oltretutto esula dall’obiet-
tivo che mi sono prefisso scrivendo questo libro e pertanto non
aggiungerò null’altro a riguardo. Tuttavia, seguiranno altri script
“simili” che dovrebbero aiutare a comprenderne meglio il fun-
zionamento.
Tornando a questo, invece, possiamo solo aggiungere qualche

120 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 121

60 SCRIPT
AMMINISTRATIVI
Avviare il controllo antivirus su di una cartella per Windows

dettaglio importante. Questo codice presuppone che sul siste-


ma ove viene lanciato, esista un software antivirus installato e
che, cliccando con il tasto destro del mouse su di una qualun-
que cartella, si acceda ad un menu ove sia presente la voce Scan
for viruses... per l’avvio dell’antivirus.
Solo in questo script è stata inserita una lista parziale di costan-
ti con prefisso “ssf” che consentono di accedere, come vedremo
in seguito, ad altri oggetti del sistema operativo. Per maggiori infor-
mazioni a riguardo, potete comunque iniziare da http://msdn.mi-
crosoft.com/library/default.asp?url=/library/en-
us/shellcc/platform/shell/programmersguide/shell_basics/shell_ba-
sics_programming/objectmap.asp.

Option Explicit

Dim objShell ' Oggetto WShell


Dim objFolder ' Oggetto Folder
Dim objVerbs ' Generico oggetto "verbo"
Dim ListaVerbi ' Stringa che memorizza la lista dei verbi
' associati al namespace considerato
Dim Item ' Generico item della collection "Verbs"
Dim objFolderSpec ' Puntatore alla cartella C:\Windows

' Const ssfDESKTOP = 0 ' Desktop (including


system items)
' Const ssfPROGRAMS = 2 ' Programs
section of Start Menu
' Const ssfCONTROLS = 3 ' Control Panel
(no path)
' Const ssfPRINTERS = 4 ' Printers (no path)
' Const ssfPERSONAL = 5 ' My Documents
' Const ssfFAVORITES = 6 ' IE Favorites
' Const ssfSTARTUP = 7 ' Startup

I libri di ioPROGRAMMO/60 script amministrativi per Windows 121


007-014 02/02/07 14:56 Pagina 122

60 SCRIPT
AMMINISTRATIVI
per Windows Avviare il controllo antivirus su di una cartella

' Const ssfRECENT = 8 ' Recent


' Const ssfSENDTO = 9 ' SendTo
' Const ssfBITBUCKET = 10 ' Recycle Bin (no path)
' Const ssfSTARTMENU = 11 ' Start Menu
' Const ssfDESKTOPDIRECTORY = 16 ' Desktop directory (no
system items)
' Const ssfDRIVES = 17 ' My Computer
' Const ssfNETWORK = 18 ' Network
Neighborhood
' Const ssfCOMMONSTARTMENU = 22 ' All users start menu
' Const ssfCOMMONFAVORITES = 31 ' All Users Favorites
' Const ssfINTERNETCACHE = 32 ' Temporary
Internet Files
' Const ssfCOOKIES = 33 ' Cookies
' Const ssfHISTORY = 34 ' History (no path)
' Const ssfPROGRAMFILES = 38 ' Program Files

Const ssfDRIVES = 17

Set objShell = CreateObject("Shell.Application")

' Considera per esempio la cartella C:\WINDOWS


Set objFolder = objShell.NameSpace(ssfDRIVES)
Set objFolderSpec = objFolder.Parsename("C:\Windows")

' Ottieni la lista dei verbi associata ad essa


Set objVerbs = objFolderSpec.Verbs

' Mostra la lista dei verbi legati all'oggetto considerato


For Each Item In objVerbs
ListaVerbi = ListaVerbi & vbCrlf & Item.Name
Next
Wscript.Echo ListaVerbi

122 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 123

60 SCRIPT
AMMINISTRATIVI
Determinare gli utenti in modalità console per Windows

' Adesso, tenuto conto che si è certi che esiste


' una riga pari a "Scan for viruses..." che consente
' l'avvio dell'antivirus, lanciamolo...
objFolderSpec.InvokeVerb "Scan for viruses..."

Set objVerbs = Nothing


Set objFolder = Nothing
Set objShell = Nothing
Set objFolderSpec = Nothing

DETERMINARE GLI UTENTI


IN MODALITÀ CONSOLE
Sfruttando WMI e servendosi più precisamente della sola clas-
se Win32_Process, possiamo determinare se esistono utenti che
sono “loggati” in modalità console ad essa. Lo script mostrato
cerca il processo Explorer e ne determina l’ID di sessione. Se è
pari a 0, allora ciò indica che un utente è in modalità console al-
la macchina. Infine, per ognuna delle macchine inserite nel file
d’input, viene registrata un’opportuna riga all’interno del re-
port indicato.

Option Explicit

Dim UserLogged ' Utente in modalità Console


Dim DomainUserLogged ' Dominio dell'utente in modalità console
Dim ConsoleUser ' Nome, completo di dominio, dell'utente in mod.
console
Dim OwnerUser ' Owner del processo
Dim OwnerDomain ' Dominio dell'owner del processo
Dim objWMIService ' Oggetto WMI
Dim objLocator ' Oggetto WMI
Dim Processes ' Collection di processi

I libri di ioPROGRAMMO/60 script amministrativi per Windows 123


007-014 02/02/07 14:56 Pagina 124

60 SCRIPT
AMMINISTRATIVI
per Windows Determinare gli utenti in modalità console

Dim Process ' Generico item della collection Processes


Dim Utente ' Utente necessario per le credenziali d'accesso
Dim Password ' Password dell'utente per l'accesso
Dim RetVal ' Memorizza i coidici di ritorno delle funzioni
Dim FSO ' Oggetto File System Object
Dim LogFile ' Report finale
Dim LeggiFile ' File con elenco server
Dim ServerCorrente ' Sistema sul quale si sta operando

' Imposta i parametri di accesso ai server


Utente = "MyDomain\Utente"
Password = "Password"

' Controlla se il file di log esiste o occorre crearlo


Set FSO = CreateObject("Scripting.FileSystemObject")
If (FSO.FileExists("ReportUserLogged.csv")) Then
Set LogFile = FSO.OpenTextFile("ReportUserLogged.csv",8)
Else
Set LogFile = FSO.CreateTextFile("ReportUserLogged.csv", True)
End If

' Apri il file contenente la lista dei server


Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Scrivi l'intestazione nel report finale


LogFile.WriteLine "Nome Server;Utente"

' Crea il report con le info di ciascun server


Do While Not LeggiFile.AtEndOfStream

' Imposta la stringa di default


ConsoleUser = "Nessun utente in modalità console"

124 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 125

60 SCRIPT
AMMINISTRATIVI
Determinare gli utenti in modalità console per Windows

ServerCorrente = LeggiFile.ReadLine
' Wscript.Echo "Sto processando il server " & ServerCorrente

' Collegati al server corrente e preleva la lista dei processi


Set objLocator = CreateObject("WbemScripting.SwbemLocator")
Set objWMIService = objLocator.ConnectServer(ServerCorrente,
"root\cimv2", Utente, Password)

Set Processes = objWMIService.InstancesOf("Win32_Process")

On Error Resume Next

' Adesso cerca il processo explorer.exe che possiede ID = 0


For Each Process In Processes
If (Process.Caption = "explorer.exe") And (Process.SessionID =
0 ) Then
RetVal = Process.GetOwner(OwnerUser, OwnerDomain)
' Controlla se ci sono stati errori
If RetVal = 0 And Err = 0 Then
ConsoleUser = OwnerDomain & "\" & OwnerUser
Msgbox ConsoleUser
Else
ConsoleUser = "Errore: " & Err.Description
End If
End If
Next

' Scrivi le informazioni trovate


LogFile.WriteLine ServerCorrente & ";" & ConsoleUser

Loop

LogFile.Close

I libri di ioPROGRAMMO/60 script amministrativi per Windows 125


007-014 02/02/07 14:56 Pagina 126

60 SCRIPT
AMMINISTRATIVI
per Windows Eliminare una connessione di rete

LeggiFile.Close

Set objWMIService = nothing


Set objLocator = Nothing
Set Processes = Nothing
Set Process = Nothing
Set FSO = Nothing
Set LogFile = Nothing
Set LeggiFile = Nothing

ELIMINARE UNA
CONNESSIONE DI RETE
Anche questo script utilizza le tecniche viste in precedenza e,
malgrado il raggiungimento di quest’operazione poteva essere
portato a termine in altro modo, il codice riportato dovrebbe
aiutare ad avvicinare l’utente che ne farà uso con meno diffiden-
za. Lo scopo dello script è proprio quello di eliminare una con-
nessione (per ipotesi quella di Loopback).

Option Explicit

Dim ConnDaEliminare ' Nome della connessione da eliminare


Dim objWShell ' Oggetto WShell
Dim objPannelloDiControllo ' Oggetto Pannello di Controllo
Dim objConnessioni ' Oggetto che punta all'item indicato
da ItemToSearch
Dim FolderItem ' FolderItem del Pannello di Controllo
Dim ItemToSearch ' Item da cercare
Dim ItemTrovato ' Flag che indica se l'item cercato è stato o
meno trovato
Dim objLanConnection ' Oggetto connessione di rete. Punta
a quella da eliminare

126 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 127

60 SCRIPT
AMMINISTRATIVI
Eliminare una connessione di rete per Windows

Dim Verb ' Generico item della collection Verbs


Dim ListaVerbs ' Elenco dei verbi

Const ssfCONTROLS = 3

' Imposta l'item del Pannello di Controllo da cercare


ItemToSearch = "Connessioni di rete"

' Imposta il flag per inizio ricerca


ItemTrovato = 0

' Impostiamo il nome della connessione da eliminare


ConnDaEliminare = " Connessione alla rete locale (LOOPBACK)"
Set objWShell = CreateObject("Shell.Application")
Set objPannelloDiControllo = objWShell.Namespace(ssfCONTROLS)
' Controlliamo tutti gli item del Pannello di Controllo
' ed individuiamo l'item "Connessioni di rete"
For Each FolderItem In objPannelloDiControllo.items
' Se desideriamo dare un'occhiata alle voci che stiamo
' scandendo, togliamo il segno di commento alla MSGBOX
' successiva.
' msgbox FolderItem.Name
If FolderItem.Name = ItemToSearch Then
' Abbiamo trovato l'item che ci serve. Possiamo anche
' uscire dal ciclo.
ItemTrovato = 1
' objConnessioni raccoglie la lista delle connessioni di rete
Set objConnessioni= FolderItem.GetFolder
Exit For
End If
Next
' Vediamo se l'item è stato trovato
If ItemTrovato = 0 Then

I libri di ioPROGRAMMO/60 script amministrativi per Windows 127


007-014 02/02/07 14:56 Pagina 128

60 SCRIPT
AMMINISTRATIVI
per Windows Disabilitare una connessione di rete

Wscript.Echo "L'item " & ItemToSearch & " non è stato trovato."
Wscript.Quit
End If

' Adesso cerca la connessione da eliminare


For Each FolderItem In objConnessioni.items
'Wscript.Echo FolderItem.Name
If LCase(FolderItem.Name) = LCase(ConnDaEliminare) Then
Set objLanConnection = FolderItem
objLanConnection.InvokeVerb("&Elimina")
Wscript.Sleep 10000
Exit For
End If
Next
' Se vogliamo, possiamo elencare tutti gli item
' della collection Verbs
' For Each verb In objLanConnection.verbs
' ListaVerbs = ListaVerbs & vbCrlf & Verb.Name
' Wscript.Echo ListaVerbs
' Next
Set objWShell = Nothing
Set objPannelloDiControllo = Nothing
Set objConnessioni = Nothing
Set FolderItem = Nothing
Set objLanConnection = Nothing
Set Verb = Nothing

DISABILITARE
UNA CONNESSIONE DI RETE
Anche questo script utilizza le tecniche viste in precedenza e,
malgrado il raggiungimento di quest’operazione poteva essere
portato a termine in altro modo, il codice riportato dovrebbe

128 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 129

60 SCRIPT
AMMINISTRATIVI
Disabilitare una connessione di rete per Windows

aiutare ad avvicinare l’utente che ne farà uso con meno diffiden-


za. Lo scopo dello script è proprio quello di disabilitare una con-
nessione (per ipotesi quella di Loopback).

Option Explicit

Dim ConnDaEliminare ' Nome della connessione da eliminare


Dim objWShell ' Oggetto WShell
Dim objPannelloDiControllo ' Oggetto Pannello di Controllo
Dim objConnessioni ' Oggetto che punta all'item indicato
da ItemToSearch
Dim FolderItem ' FolderItem del Pannello di Controllo
Dim ItemToSearch ' Item da cercare
Dim ItemTrovato ' Flag che indica se l'item cercato è stato o
meno trovato
Dim objLanConnection ' Oggetto connessione di rete. Punta
a quella da eliminare
Dim Verb ' Generico item della collection Verbs
Dim ListaVerbs ' Elenco dei verbi

Const ssfCONTROLS = 3

' Imposta l'item del Pannello di Controllo da cercare


ItemToSearch = "Connessioni di rete"

' Imposta il flag per inizio ricerca


ItemTrovato = 0

' Impostiamo il nome della connessione da eliminare


ConnDaEliminare = "Connessione alla rete locale (LOOPBACK)"

Set objWShell = CreateObject("Shell.Application")


Set objPannelloDiControllo = objWShell.Namespace(ssfCONTROLS)

I libri di ioPROGRAMMO/60 script amministrativi per Windows 129


007-014 02/02/07 14:56 Pagina 130

60 SCRIPT
AMMINISTRATIVI
per Windows Disabilitare una connessione di rete

' Controlliamo tutti gli item del Pannello di Controllo


' ed individuiamo l'item "Connessioni di rete"
For Each FolderItem In objPannelloDiControllo.items
' Se desideriamo dare un'occhiata alle voci che stiamo
' scandendo, togliamo il segno di commento alla MSGBOX
' successiva.
msgbox FolderItem.Name
If FolderItem.Name = ItemToSearch Then
' Abbiamo trovato l'item che ci serve. Possiamo anche
' uscire dal ciclo.
ItemTrovato = 1
' objConnessioni raccoglie la lista delle connessioni di rete
Set objConnessioni= FolderItem.GetFolder
Exit For
End If
Next

' Vediamo se l'item è stato trovato


If ItemTrovato = 0 Then
Wscript.Echo "L'item " & ItemToSearch & " non è stato trovato."
Wscript.Quit
End If

' Adesso cerca la connessione da eliminare


For Each FolderItem In objConnessioni.items
'Wscript.Echo FolderItem.Name
If LCase(FolderItem.Name) = LCase(ConnDaEliminare) Then
Set objLanConnection = FolderItem
objLanConnection.InvokeVerb("&Disabilita")
Wscript.Sleep 10000
Exit For
End If
Next

130 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 131

60 SCRIPT
AMMINISTRATIVI
Disabilitare una connessione di rete per Windows

' Se vogliamo, possiamo elencare tutti gli item


' della collection Verbs
' For Each verb In objLanConnection.verbs
' ListaVerbs = ListaVerbs & vbCrlf & Verb.Name
' Wscript.Echo ListaVerbs
' Next

Set objWShell = Nothing


Set objPannelloDiControllo = Nothing
Set objConnessioni = Nothing
Set FolderItem = Nothing
Set objLanConnection = Nothing
Set Verb = Nothing
Elencare i Documenti Recenti
Questo script ottiene l’elenco dei documenti recenti utilizzando una
tecnica simile alla precedente.

Option Explicit

Dim objWShell ' Oggetto WShell


Dim FolderItem ' Generico item dei documenti recenti
Dim objDocumentiRecenti ' Oggetto namspace Documenti
Recenti
Dim ListaDocRecenti ' Lista dei documenti recenti

Const ssfRECENT = 8

' Creiamo l'oggetto che punta ai documenti recenti


Set objWShell = CreateObject("Shell.Application")
Set objDocumentiRecenti = objWShell.Namespace(ssfRECENT)

' Controlliamo tutti gli item relativi ai documenti recenti


For Each FolderItem In objDocumentiRecenti.items

I libri di ioPROGRAMMO/60 script amministrativi per Windows 131


007-014 02/02/07 14:56 Pagina 132

60 SCRIPT
AMMINISTRATIVI
per Windows Disabilitare una connessione di rete

' Mostriamo l'elenco dei documenti recenti.


ListaDocRecenti = ListaDocRecenti & vbCrlf & FolderItem.Name
Next

Msgbox ListaDocRecenti

Set objWShell = Nothing


Set objDocumentiRecenti = Nothing
Set FolderItem = Nothing
Elencare i documenti nel Cestino
Questo script consente di controllare ed ottenere la lista dei file
presenti nel Cestino.

Option Explicit

Dim objWShell ' Oggetto WShell


Dim FolderItem ' Generico oggetto del Cestino
Dim objDocumentiCestino ' Oggetto namespace Cestino
Dim ListaDocCestino ' Lista dei documenti del Cestino
Dim ItemSize ' Dimensione dell'oggetto nel Cestino

Const ssfBITBUCKET = 10

' Di seguito l'elenco del secondo parametro del metodo GetDetailsOf()


– Fonte MS
' 0 Retrieves the name of the item.'
' 1 Retrieves the size of the item.
' 2 Retrieves the type of the item.
' 3 Retrieves the date and time that the item was last modified.
' 4 Retrieves the attributes of the item.
' -1 Retrieves the info tip information for the item.

‘ Impostiamo l’informazione Size

132 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 133

60 SCRIPT
AMMINISTRATIVI
Controllare l’abilitazione al controllo remoto per Windows

Const iColumn = 3

' Creiamo l'oggetto che punta ai documenti del Cestino


Set objWShell = CreateObject("Shell.Application")
Set objDocumentiCestino = objWShell.Namespace(ssfBITBUCKET)

' Controlliamo tutti gli item del Cestino


For Each FolderItem In objDocumentiCestino.items
' Mostriamo l'elenco dei documenti del Cestino.
ItemSize = objDocumentiCestino.GetDetailsOf(FolderItem,
iColumn)
ListaDocCestino = ListaDocCestino & " " & FolderItem.Name &
" " & " " & ItemSize & vbCrlf
Next

Msgbox "NUMERO TOTALE: " & objDocumentiCestino.Items.Count &


vbcrlf & ListaDocCestino

Set objWShell = Nothing


Set objDocumentiCestino = Nothing
Set FolderItem = Nothing

CONTROLLARE L’ABILITAZIONE
AL CONTROLLO REMOTO
Questo script crea un report di tutti i sistemi che hanno preim-
postato l’accesso al sistema mediante Remote Desktop. Per ef-
fettuare questo controllo, lo script verifica il valore di una oppor-
tuna chiave del Registry denominata fsDenyTSConnections.

Option Explicit

Dim WSHShell ' Oggetto WShell

I libri di ioPROGRAMMO/60 script amministrativi per Windows 133


007-014 02/02/07 14:56 Pagina 134

60 SCRIPT
AMMINISTRATIVI
per Windows Controllare l’abilitazione al controllo remoto

Dim RegKey ' Chiave del Registry


Dim FSO ' Oggetto FSO
Dim LeggiFile ' Puntatore al file contenente l'elenco dei
server
Dim LogFile ' Puntatore al file di log
Dim ServerCorrente ' Generico server
Dim rRegistry ' Oggetto WMI
Dim strKeyPath ' Percorso del Registry ove reperire le info
Dim fDenyTSConnection ' Chiave del Registry che indica la possibilità
o meno di collegarsi da remoto
Dim dwfDenyTSConnection ' Memorizza il valore
DWORD recuperato dal Registry
Dim Utente ' Utente utile per l'accesso al sistema
Dim Password ' Password dell'utente utile per
l'accesso al sistema
Dim objLocator ' Oggetto WMI
Dim objWMIService ' Oggetto WMI
Dim RetVal ' Valore di ritorno del metodo
GetDWORDValue()

Const HKEY_LOCAL_MACHINE = &H80000002

' Imposta le credenziali dell’utente


Utente = "MyDomain\Utente"
Password = "Password"

fDenyTSConnection = "fDenyTSConnections"

' Preleva l'elenco dei server su cui effettuare il controllo


Set FSO = CreateObject("Scripting.FileSystemObject")
Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Controlla se il file di log esiste o occorre crearlo

134 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 135

60 SCRIPT
AMMINISTRATIVI
Controllare l’abilitazione al controllo remoto per Windows

If (FSO.FileExists("ReportTS.csv")) Then
Set LogFile = FSO.OpenTextFile("ReportTS.csv",8)
Else
Set LogFile = FSO.CreateTextFile("ReportTS.csv", True)
End If

' CHIAVE DA LEGGERE:


'
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal
Server
' -> fDenyTSConnections
' 1 (Remote Desktop disabled)
' 0 (Remote Desktop enabled)
'

' Leggi il file con l'elenco dei server e, per ognuno, leggi
' le informazioni che trovi nel Registry

LogFile.WriteLine "SERVER;REGISTRY VAL"

Do While Not LeggiFile.AtEndOfStream

dwfDenyTSConnection = 0
ServerCorrente = LeggiFile.ReadLine

' Collegati al server remoto corrente


Set objLocator = CreateObject("WbemScripting.SwbemLocator")
Set objWMIService = objLocator.ConnectServer(ServerCorrente,
"/root/default", Utente, Password)
Set rRegistry = objWMIService.Get("StdRegProv")

strKeyPath = "SYSTEM\CurrentControlSet\Control\Terminal
Server"

I libri di ioPROGRAMMO/60 script amministrativi per Windows 135


007-014 02/02/07 14:56 Pagina 136

60 SCRIPT
AMMINISTRATIVI
per Windows Controllare l’esecuzione di uno script

RetVal = rRegistry.GetDWORDValue
(HKEY_LOCAL_MACHINE,strKeyPath,fDenyTSConnection,dwfDenyTSC
onnection)

If RetVal <> 0 Then


' La chiave potrebbe anche non esistere...
' Per default = 0
LogFile.WriteLine ServerCorrente & ";" & "ERRORE"
Else
LogFile.WriteLine ServerCorrente & ";" &
Cstr(dwfDenyTSConnection)
End If

Loop

LeggiFile.Close
LogFile.Close

Set WSHShell = Nothing


Set FSO = Nothing
Set LeggiFile = Nothing
Set LogFile = Nothing
Set rRegistry = Nothing
Set objLocator = Nothing
Set objWMIService = Nothing

Wscript.Echo "Ho terminato"

CONTROLLARE
L’ESECUZIONE DI UNO SCRIPT
Questo piccolo script consente di controllare se un determina-

136 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 137

60 SCRIPT
AMMINISTRATIVI
Controllare l’esecuzione di uno script per Windows

to “altro” script VBS sta girando ed, in caso non lo fosse, con-
sente di avviarlo in maniera nascosta. Per ipotesi, il nome del-
lo script, completo di percorso, è C:\IPAddress.vbs. Questo pic-
colo programma cerca tra i processi la lista di quelli denomina-
ti wscript o cscript. In seguito, senza preoccuparsi se la collec-
tion è formata da almeno un elemento (lo è sicuramente perché
lo script corrente crea proprio un processo di questo tipo), cer-
ca nella proprietà CommandLine che riporta l’esatto comando
avviato (qualcosa del tipo “c:\cscript.exe” “c:\IPAddress.vbs”).
Se non trova nulla, allora mostra un popup per 3 secondi e poi
avvia un processo nascosto che lancia il vbs.

Option Explicit

Dim NomeScript ' Nome dello script da controllare


Dim strComputer ' Nome del computer su cui operare
Dim objWMIService ' Oggetto WMI
Dim colProcesses ' Collection di processi
Dim objWSHShell ' Oggetto Shell
Dim newProcess ' Nuovo processo per il lancio dello script
Dim Trovato ' Flag che indica se lo script sta girando oppure
no
Dim objStartup ' Oggetto classe Win32_ProcessStartup
Dim objProcess ' Generico item collection di processi
Dim objConfig ' Oggetto per la configurazione del nuovo
processo
Dim intProcessID ' Parametro ID processo
Dim RetVal ' Valore di ritorno del metotdo Create, classe
Win32_Process

Const POPUP_DURATION = 3
Const OK_BUTTON = 0
Const HIDDEN_WINDOW = 12

I libri di ioPROGRAMMO/60 script amministrativi per Windows 137


007-014 02/02/07 14:56 Pagina 138

60 SCRIPT
AMMINISTRATIVI
per Windows Controllare l’esecuzione di uno script

NomeScript = "C:\IPAddress.vbs"
strComputer = "."
Trovato = False

Set objWSHShell = Wscript.CreateObject("Wscript.Shell")

Set objWMIService = GetObject("winmgmts:" _


& "{impersonationLevel=impersonate}!\\" &
strComputer & "\root\cimv2")

' Verifica se esistono processi WSCRIPT o CSCRIPT che potrebbero far


' pensare che il VBS è stato avviato e sta girando.
Set colProcesses = objWMIService.ExecQuery("SELECT * FROM
Win32_Process WHERE Name = " & _
"'wscript.exe' OR Name= 'cscript.exe'")

' Controlla se lo script sta girando oppure no


For Each objProcess In colProcesses
If Instr(objProcess.CommandLine,NomeScript) <> 0 Then
Trovato = True
Exit For
End If
Next

' Se Trovato = False, allora lo script va rilanciato...


' Per far questo creiamo un processo "nascosto"...
If Trovato = False Then
objWshShell.Popup "Lo script sicuramente non è stato avviato." &
vbCrlf & "Occorre rilanciarlo...", POPUP_DURATION,

"Errore", OK_BUTTON
Set newProcess =
GetObject("winmgmts:root\cimv2:Win32_Process")

138 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 139

60 SCRIPT
AMMINISTRATIVI
Eseguire uno script direttamente su macchine remote per Windows

' Imposta la configurazione per avviare un processo nascosto


Set objStartup = objWMIService.Get("Win32_ProcessStartup")
Set objConfig = objStartup.SpawnInstance_
objConfig.ShowWindow = HIDDEN_WINDOW
RetVal = newProcess.Create("cscript.exe " & NomeScript, Null,
objConfig, intProcessID)
End If

Set objWMIService = Nothing


Set colProcesses = Nothing
Set objWSHShell = Nothing
Set newProcess = Nothing
Set objStartup = Nothing
Set objProcess = Nothing
Set objConfig = Nothing

ESEGUIRE UNO SCRIPT


DIRETTAMENTE SU MACCHINE
REMOTE
Questo è uno script davvero particolare perché, contrariamen-
te a quanto abbiamo visto nei precedenti listati, il processo
Wscript generato dall’avvio di uno qualunque dei codice sino-
ra visti, non avviene sulla macchina sorgente, bensì su quella di
destinazione. Affinché tutto funzioni, però, sono necessari al-
cuni accorgimenti che devono essere rispettati e che “sinteti-
camente” si concretizzano nella modifica di una chiave del Re-
gistry, sia locale che del sistema remoto.
L’oggetto che permette di effettuare questo tipo di esecuzione
è denominato WSHController (ne esistono comunque altri a con-
torno) e attraverso essi è possibile controllare lo stato di esecu-
zione dello script, comportandosi di conseguenza.
Maggiori dettagli in proposito possono essere recuperati dal si-

I libri di ioPROGRAMMO/60 script amministrativi per Windows 139


007-014 02/02/07 14:56 Pagina 140

60 SCRIPT
AMMINISTRATIVI
per Windows Eseguire uno script direttamente su macchine remote

to della Microsoft e più precisamente da www.microsoft.co.ke/te-


chnet/scriptcenter/topics/remote/rscripting.mspx. Al suo interno
vengono spiegati i dettagli di una simile tecnica ed eventuali
consigli per evitare gli errori più comuni.

Option Explicit

Dim LeggiFile ' Puntatore al file contenente la lista dei server


Dim objController ' Oggetto WSHController
Dim RemoteScript ' Script da avviare sul server remoto
Dim FSO ' Oggetto File System Object
Dim LogFile ' Puntatore al file di log
Dim ServerCorrente ' Server su cui operare
Dim ScriptDaAvviare ' Script, completo di percorso, da avviare
Dim strKeyPath ' Chiave del Registry per l'avvio di script remoti
Dim objRegProv ' Oggetto Registry Provider

Const NOTASK = 0 ' Lo script è stato creato ma non ancora


eseguito.
Const RUNNING = 1 ' Lo script remoto è in stato RUNNING.
Const FINISHED = 2 ' Lo script remoto ha terminato l'esecuzione.

Const HKEY_LOCAL_MACHINE = &H80000002

' Imposta la chiave del Registry per l'avvio di script remoti


strKeyPath = "SOFTWARE\Microsoft\Windows Script Host\Settings"

' Imposta lo script da avviare sulla macchina remota. Per ipotesi


Installed_Hotfix.vbs
ScriptDaAvviare = "C:\Installed_Hotfix.vbs"

' Preleva l'elenco dei server su cui effettuare il controllo


Set FSO = CreateObject("Scripting.FileSystemObject")

140 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 141

60 SCRIPT
AMMINISTRATIVI
Eseguire uno script direttamente su macchine remote per Windows

Set LeggiFile = FSO.OpenTextFile("ElencoServer.txt")

' Prepara il file di log


If (FSO.FileExists("RemoteScript.log")) Then
Set LogFile = FSO.OpenTextFile("RemoteScript.log",8)
Else
Set LogFile = FSO.CreateTextFile("RemoteScript.Log", True)
End If

' Inserisci l'intestazione nel file di log


LogFile.WriteLine "SERVER;SCRIPT STATUS;ERROR"

' Crea l'oggetto


Set objController = WScript.CreateObject("WSHController")

' Avvia lo script sulla macchina remota


Do While Not LeggiFile.AtEndOfStream

ServerCorrente = LeggiFile.ReadLine

' Imposta a 1 il flag del Registry per l'avvio


' remoto di uno script.
' HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Script
Host\Settings\Remote = 1

Set objRegProv =
GetObject("winmgmts:{impersonationLevel=Impersonate}" & _
"!\\" & ServerCorrente &
"\root\default:StdRegProv")

objRegProv.SetStringValue
HKEY_LOCAL_MACHINE,strKeyPath,"Remote","1"

I libri di ioPROGRAMMO/60 script amministrativi per Windows 141


007-014 02/02/07 14:56 Pagina 142

60 SCRIPT
AMMINISTRATIVI
per Windows Eseguire uno script direttamente su macchine remote

' Crea l'oggetto


Set RemoteScript = objController.CreateScript(ScriptDaAvviare,
ServerCorrente)

' Avvia lo script sull'host remoto


Wscript.ConnectObject RemoteScript, "Remote_"
RemoteScript.Execute

' Controlla lo stato dello script


Do While RemoteScript.Status <> FINISHED
WScript.Sleep 100
Loop

If Not RemoteScript.Error Then


LogFile.WriteLine ServerCorrente & ";OK;"
End If

' Disconnetti l'oggetto


Wscript.DisconnectObject RemoteScript

Loop

Sub Remote_Error

LogFile.WriteLine ServerCorrente & ";ERR;" & RemoteScript.Error

End Sub

LeggiFile.Close
LogFile.Close

Set LeggiFile = Nothing


Set objController = Nothing

142 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 143

60 SCRIPT
AMMINISTRATIVI
IIS: Prelevare informazioni sui Web Site per Windows

Set RemoteScript = Nothing


Set FSO = Nothing
Set LogFile = Nothing
Set objRegProv = Nothing

IIS: PRELEVARE INFORMAZIONI


SUI WEB SITE
Questo script si occupa di elencare alcune delle principali infor-
mazioni riguardanti i Web Site di IIS. Ovviamente l’elenco dei
dettagli non è molto esaustivo (in particolare si è posto maggio-
re attenzione sullo stato del sito piuttosto che su altre informa-
zioni). In ogni caso, dovrebbe essere sufficiente a mostrare co-
me utilizzare il provider IIS.
Solo un dettaglio importante prima di passare allo script. Ogni
Web Site è identificato da un nome che, in realtà, è un indice nu-
merico progressivo. Qualora fosse necessario interrogare lo sta-
to di uno in particolare, sarà sufficiente sostituire la stringa AD-
sPath inserita nello script con un’analoga costruita ad hoc e si-
mile alla seguente:

Set objWebServer = GetObject("IIS://" & ServerIIS & "/W3SVC/” &


Indice)

dove Indice è, per l’appunto, l’identificativo del Web Site interes-


sato.

Option Explicit

Dim ServerIIS ' Server IIS


Dim objWebServer ' Oggetto ADSI
Dim Site ' Generico sito
Dim SiteStatus(9) ' Stato del sito

I libri di ioPROGRAMMO/60 script amministrativi per Windows 143


007-014 02/02/07 14:56 Pagina 144

60 SCRIPT
AMMINISTRATIVI
per Windows IIS: Prelevare informazioni sui Web Site

Const MD_SERVER_STATE_STARTING = 1
Const MD_SERVER_STATE_STARTED = 2
Const MD_SERVER_STATE_STOPPING = 3
Const MD_SERVER_STATE_STOPPED = 4
Const MD_SERVER_STATE_PAUSING = 5
Const MD_SERVER_STATE_PAUSED = 6
Const MD_SERVER_STATE_CONTINUING = 7

SiteStatus(1) = "STARTING"
SiteStatus(2) = "STARTED"
SiteStatus(3) = "STOPPING"
SiteStatus(4) = "STOPPED"
SiteStatus(5) = "PAUSING"
SiteStatus(6) = "PAUSED"
SiteStatus(7) = "CONTINUING"
SiteStatus(8) = "SCONOSCIUTO"

' Controlla se allo script è stato passato il parametro


' SERVER. In caso contrario, sfrutta LOCALHOST

If WScript.Arguments.Named.Exists("SERVER") Then
ServerIIS = WScript.Arguments.Named("SERVER")
Else
ServerIIS = "localhost"
End If

' Scrivi a video i dettagli


WScript.Echo "Dettagli IIS server " & Ucase(ServerIIS)

' Ottieni il riferimento al server


Set objWebServer = GetObject("IIS://" & ServerIIS & "/W3SVC")

144 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 145

60 SCRIPT
AMMINISTRATIVI
IIS: Prelevare informazioni sugli FTP Site per Windows

' Mostra i dati principali dei siti Web

For Each Site In objWebServer


IF Site.Class = "IIsWebServer" THEN
WScript.Echo _
"Site Name (ID) = " & Site.Name & vbCrlf & _
"Server Comment = """ & Site.ServerComment & """ "
& vbCrlf & _
"Server State = " & SiteStatus(Site.ServerState)
& vbCrlf & _
"LogFileDir = " & Site.LogFileDirectory & _
""
End If
Next

IIS: PRELEVARE INFORMAZIONI


SUGLI FTP SITE
Questo script si occupa di elencare alcune delle principali infor-
mazioni riguardanti gli FTP Site di IIS. Ovviamente l’elenco dei
dettagli non è molto esaustivo (in particolare si è posto maggio-
re attenzione sullo stato del sito piuttosto che su altre informa-
zioni). In ogni caso, dovrebbe essere sufficiente a mostrare co-
me utilizzare il provider IIS. Contrariamente allo script prece-
dente, la principale (e forse unica) differenza degna di nota è
la stringa AdsPath specificata per il collegamento al server. In-
fatti, mentre nel primo caso avevamo:

Set objWebServer = GetObject("IIS://" & ServerIIS & "/W3SVC")

nel presente abbiamo

Set objFTPServer = GetObject("IIS://" & ServerIIS & "/MSFTPSVC")

I libri di ioPROGRAMMO/60 script amministrativi per Windows 145


007-014 02/02/07 14:56 Pagina 146

60 SCRIPT
AMMINISTRATIVI
per Windows IIS: Prelevare informazioni sugli FTP Site

Option Explicit

Dim ServerIIS ' Server IIS


Dim objFTPServer ' Oggetto ADSI
Dim Site ' Generico sito
Dim SiteStatus(9) ' Stato del sito

Const MD_SERVER_STATE_STARTING = 1
Const MD_SERVER_STATE_STARTED = 2
Const MD_SERVER_STATE_STOPPING = 3
Const MD_SERVER_STATE_STOPPED = 4
Const MD_SERVER_STATE_PAUSING = 5
Const MD_SERVER_STATE_PAUSED = 6
Const MD_SERVER_STATE_CONTINUING = 7

SiteStatus(1) = "STARTING"
SiteStatus(2) = "STARTED"
SiteStatus(3) = "STOPPING"
SiteStatus(4) = "STOPPED"
SiteStatus(5) = "PAUSING"
SiteStatus(6) = "PAUSED"
SiteStatus(7) = "CONTINUING"
SiteStatus(8) = "SCONOSCIUTO"

' Controlla se allo script è stato passato il parametro


' SERVER. In caso contrario, sfrutta LOCALHOST

If WScript.Arguments.Named.Exists("SERVER") Then
ServerIIS = WScript.Arguments.Named("SERVER")
Else
ServerIIS = "localhost"
End If

146 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 147

60 SCRIPT
AMMINISTRATIVI
IIS: Creare e cancellare Web Site ed FTP Site per Windows

' Scrivi a video i dettagli


WScript.Echo "Dettagli IIS server " & Ucase(ServerIIS)

' Ottieni il riferimento al server


Set objFTPServer = GetObject("IIS://" & ServerIIS & "/MSFTPSVC")

' Mostra i dati principali dei siti Web

For Each Site In objFTPServer


IF Site.Class = "IIsWebServer" THEN
WScript.Echo _
"Site Name (ID) = " & Site.Name & vbCrlf & _
"Server Comment = """ & Site.ServerComment & """ "
& vbCrlf & _
"Server State = " & SiteStatus(Site.ServerState)
& vbCrlf & _
"LogFileDir = " & Site.LogFileDirectory & _
""
End If
Next

IIS: CREARE E CANCELLARE


WEB SITE ED FTP SITE
In questo script vengono utilizzate alcune delle conoscenze ac-
quisite precedentemente per creare o cancellare “oggetti” Web
Site e FTP Site attraverso VBS. Naturalmente, poche righe di co-
dice non esauriscono le tante possibilità di parametrizzazione e
personalizzazione di questi componenti di IIS, ma danno co-
munque un’idea di quello che si può/deve fare per manipolar-
li.

Option Explicit

I libri di ioPROGRAMMO/60 script amministrativi per Windows 147


007-014 02/02/07 14:56 Pagina 148

60 SCRIPT
AMMINISTRATIVI
per Windows IIS: Creare e cancellare Web Site ed FTP Site

Dim ServerIIS ' Server IIS


Dim objWebServer ' Oggetto ADSI
Dim Site ' Generico sito
Dim SiteStatus(9) ' Stato del sito
Dim OperationFlag ' Operazione da effettuare
(creazione o cancellazione)
Dim WEB_FTP_Flag ' Flag per controllare su cosa agire

Const MD_SERVER_STATE_STARTING = 1
Const MD_SERVER_STATE_STARTED = 2
Const MD_SERVER_STATE_STOPPING = 3
Const MD_SERVER_STATE_STOPPED = 4
Const MD_SERVER_STATE_PAUSING = 5
Const MD_SERVER_STATE_PAUSED = 6
Const MD_SERVER_STATE_CONTINUING = 7

SiteStatus(1) = "STARTING"
SiteStatus(2) = "STARTED"
SiteStatus(3) = "STOPPING"
SiteStatus(4) = "STOPPED"
SiteStatus(5) = "PAUSING"
SiteStatus(6) = "PAUSED"
SiteStatus(7) = "CONTINUING"
SiteStatus(8) = "SCONOSCIUTO"

' Controlla se allo script è stato passato il parametro


' SERVER. In caso contrario, sfrutta LOCALHOST

If WScript.Arguments.Named.Exists("SERVER") Then
ServerIIS = WScript.Arguments.Named("SERVER")
Else
ServerIIS = "localhost"

148 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 149

60 SCRIPT
AMMINISTRATIVI
IIS: Creare e cancellare Web Site ed FTP Site per Windows

End If

' Controlla se allo script è stato passato il parametro


' per i Web Site o per gli FTP Site.

' Se è stato passato il parametro W (per i Web Site)...


If WScript.Arguments.Named.Exists("W") Then
WEB_FTP_Flag = "W"
Else
If WScript.Arguments.Named.Exists("F") Then
WEB_FTP_Flag = "F"
Else
MsgBox "Errore! Non hai specificato correttamente
i parametri."
WScript.Quit
End If
End If

' Controlla se allo script è stato passato il parametro


' per la creazione o l'eliminazione.

' Se è stato passato il parametro C (creazione)...


If WScript.Arguments.Named.Exists("C") Then
OperationFlag = "C"
Else
If WScript.Arguments.Named.Exists("D") Then
OperationFlag = "D"
' Controlla che sia stato specificato l'indice
' dell'oggetto da eliminare
If Not WScript.Arguments.Named.Exists("INDEX") Then
MsgBox "Errore! Non hai specificato l'ID."
WScript.Quit
End If

I libri di ioPROGRAMMO/60 script amministrativi per Windows 149


007-014 02/02/07 14:56 Pagina 150

60 SCRIPT
AMMINISTRATIVI
per Windows IIS: Creare e cancellare Web Site ed FTP Site

Else
MsgBox "Errore! Non hai specificato correttamente
i parametri."
WScript.Quit
End If
End If

' Adesso controlla che operazione compiere


' C = Creazione
' D = Eliminazione

' PS: Per default si considera un'operazione di creazione/cancellazione


' di FTP Site quando il parametro /W non è specificato
Select Case OperationFlag
Case "C"
If WEB_FTP_Flag = "W" Then
CreaWebSite
Else
CreaFTPSite
End If
Case "D"
If WEB_FTP_Flag = "W" Then
EliminaWebSite
Else
EliminaFTPSite
End If
End Select

Public Sub CreaWebSite


Dim NewSite
Dim NewRoot
Dim SiteTCPPort
Dim SiteIPAddress

150 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 151

60 SCRIPT
AMMINISTRATIVI
IIS: Creare e cancellare Web Site ed FTP Site per Windows

Dim Index
Dim SiteName
Dim SitePath
Dim WebSite

SiteName = "My Web Site"


SitePath = "C:\Inetpub\wwwroot"

' Ottieni il riferimento all'oggetto di IIS


Set Site = GetObject("IIS://" & ServerIIS & "/W3SVC")

' Determina l'indice valido


For Each WebSite In Site
If IsNumeric(WebSite.Name) Then
If Index < WebSite.Name Then
Index = WebSite.Name
End If
End If
Next

' Ecco l'indice valido...


Index = Index + 1

' Impostiamo l'indirizzo IP e la porta di ascolto del Web Server


SiteIPAddress = "10.0.0.2"
SiteTCPPort = "80"

' Creiamo l'oggetto


Set NewSite = Site.Create("IIsWebServer", Index)
' Impostiamo alcune caratteristiche e salviamo
NewSite.ServerBindings = Array(SiteIPAddress & ":
" & SiteTCPPort & ":")
NewSite.ServerComment = SiteName

I libri di ioPROGRAMMO/60 script amministrativi per Windows 151


007-014 02/02/07 14:56 Pagina 152

60 SCRIPT
AMMINISTRATIVI
per Windows IIS: Creare e cancellare Web Site ed FTP Site

NewSite.SetInfo
Set NewRoot = NewSite.Create("IIsWebVirtualDir", "Root")
NewRoot.Path = SitePath
NewRoot.SetInfo

End Sub

Public Sub CreaFTPSite

Dim FTPSiteName
Dim SitePath
Dim SiteIPAddress
Dim SiteTCPPort
Dim FTPSite
Dim NewSite
Dim NewRoot
Dim Index

' Imposta la descrizione dell'FTP site


FTPSiteName = "My FTP Site"

' Imposta il site path


SitePath = "C:\Inetpub\MyFTPPath"

' Imposta l'indirizzo IP e la porta


SiteIPAddress = "10.0.0.2"
SiteTCPPort = "21"

' Otteniamo il riferimento


Set Site = GetObject("IIS://" & ServerIIS & "/MSFTPSVC")

' Determina l'indice valido


For Each FTPSite In Site

152 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 153

60 SCRIPT
AMMINISTRATIVI
IIS: Creare e cancellare Web Site ed FTP Site per Windows

If IsNumeric(FTPSite.Name) Then
If Index < FTPSite.Name Then
Index = FTPSite.Name
End if
End If
Next

Index = Index + 1

' Completiamo la creazione


Set NewSite = Site.Create("IIsFTPServer", Index)
NewSite.ServerComment = FTPSiteName
NewSite.ServerBindings = Array(SiteIPAddress & ":
" & SiteTCPPort & ":")
NewSite.SetInfo

Set NewRoot = NewSite.Create("IIsFTPVirtualDir", "Root")


NewRoot.Path = SitePath
NewRoot.SetInfo

End Sub

Public Sub EliminaWebSite

Dim Site

Set Site = GetObject("IIS://" & ServerIIS & "/W3SVC")

Site.Delete "IIsWebServer", Wscript.Arguments.Named("INDEX")

End Sub

I libri di ioPROGRAMMO/60 script amministrativi per Windows 153


007-014 02/02/07 14:56 Pagina 154

60 SCRIPT
AMMINISTRATIVI
per Windows IIS: Creare e cancellare Web Site ed FTP Site

Public Sub EliminaFTPSite

Dim FTPSite

Set FTPSite = GetObject("IIS://" & ServerIIS & "/MSFTPSVC")

FTPSite.Delete "IIsFTPServer", Wscript.Arguments.Named("INDEX")

End Sub

154 I libri di ioPROGRAMMO/60 script amministrativi per Windows


007-014 02/02/07 14:56 Pagina 155

NOTE
007-014 02/02/07 14:56 Pagina 156
007-014 02/02/07 14:56 Pagina 157
007-014 02/02/07 14:56 Pagina 158
007-014 02/02/07 14:56 Pagina 159
007-014 02/02/07 14:56 Pagina 160

i libri di

60 SCRIPT AMMINISTRATIVI
PER WINDOWS
Autore: Francesco Lippo

EDITORE
Edizioni Master S.p.A.
Sede di Milano:Via Ariberto, 24 - 20123 Milano
Sede di Rende: C.da Lecco, zona ind. - 87036 Rende (CS)
Realizzazione grafica:
Cromatika Srl
C.da Lecco, zona ind. - 87036 Rende (CS)
Art Director: Paolo Cristiano
Responsabile grafico di progetto: Salvatore Vuono
Coordinatore tecnico: Giancarlo Sicilia
Illustrazioni: Tonino Intieri
Impaginazione elettronica: Francesco Cospite

Servizio Clienti
Tel. 02 831212 - Fax 02 83121206
@ e-mail: customercare@edmaster.it

Stampa: Grafica Editoriale Printing - Bologna

Finito di stampare nel mese di Febbraio 2007

Il contenuto di quest’opera, anche se curato con scrupolosa attenzione, non può


comportare specifiche responsabilità per involontari errori, inesattezze o uso scorret-
to. L’editore non si assume alcuna responsabilità per danni diretti o indiretti causati
dall’utilizzo delle informazioni contenute nella presente opera. Nomi e marchi
protetti sono citati senza indicare i relativi brevetti. Nessuna parte del testo può esse-
re in alcun modo riprodotta senza autorizzazione scritta della Edizioni Master.

Copyright © 2007 Edizioni Master S.p.A.


Tutti i diritti sono riservati.