Archives For Script

Articolo “appunti“, come sporadicamente capita qui sopra. Ho avuto la necessità di rimuovere delle mappature verso stampanti di rete non più raggiungibili (cambio server remoto di stampa, nda), tutte queste non controllate da GPO (erano state aggiunte manualmente dagli utenti). Ho aggirato l’ostacolo con alcune righe di VBScript. Le ritrovi qui di seguito nel caso in cui dovessero servirti.

VBScript: rimuovere mappature stampanti (Coding)

Pulizia completa (da server)

Ti ricordo che il VBScript può essere eseguito manualmente, o inserito in un più complesso (e completo) script di Logon, o magari puoi pensare di lanciarlo su altre macchine passando per PSExec o qualsiasi altro strumento di gestione postazioni come Kace (o equivalenti).

Dim objWMIService, objNetwork, colInstalledPrinters, objPrinter
strComputer = "."
i = 0
PrintServer = "NOME-VECCHIO-SERVER"
Set objWMIService = GetObject("winmgmts:" _
 & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colInstalledPrinters = objWMIService.ExecQuery _
 ("Select * from Win32_Printer")
 For Each objPrinter in colInstalledPrinters
 ReDim Preserve arrPrinterName(i)
 arrPrinterName(i) = objPrinter.Name
 If InStr(arrPrinterName(i), PrintServer) Then
 Set objNetwork = WScript.CreateObject("WScript.Network")
 objNetwork.RemovePrinterConnection arrPrinterName(i)
 i=i+1 
 Else
 End If
Next

Il nome del server viene dichiarato come variabile PrintServer (facile intuirlo, eh?), devi praticamente sostituire quell’unica cosa lasciando invariato il resto.

e qualcosina da locale

Sì, perché potrebbe anche capitare che –contestualmente– ci sia qualcosa installato in locale sulla macchina (e non solo figlio del tasto destro → connetti), anch’esso non più utile alla quotidianità dell’utente. A questo punto però, contrariamente alla porzione di script di prima, ricorda che per quella di seguito servirà essere amministratori del PC (quindi bisognerà lanciare lo script come tali, o trovare un’alternativa):

arrDeletePrinters = Array("STAMPANTE1","STAMPANTE2","STAMPANTE3")
For Each objPrinter in colInstalledPrinters
 For Each strPrinter in arrDeletePrinters
 If Not InStr(1, objPrinter.DeviceID, strPrinter, 1) = 0 Then
 objPrinter.Delete_ 
 End If
 Next
Next

dove al posto di STAMPANTE1, STAMPANTE2, STAMPANTE3(volendo puoi dichiararne ancora, o toglierne, se necessario), dovrai inserire quelle che realmente vuoi eliminare, basta il nome con il quale è stata dichiarata (ogni singola stampante) sul sistema, ammesso che qualcuno non abbia avuto la malsana idea di nominarle in maniera differente ogni volta.

Ovviamente non è detto che tu abbia necessità di entrambe le soluzioni, puoi quindi limitarti a riportare la prima parte dello script in un tuo file (.vbs) da salvare dove più ritieni opportuno (in modo tale che sia raggiungibile dalle tue postazioni, chiaramente), o magari solo la seconda, stando però attento a includergli in testa il blocco relativo alla preparazione variabili e funzioni da richiamare (Dim objWMIService, objNetwork, colInstalledPrinters, objPrinter, la parte relativa a strComputer e il Set objWMIService = GetObject(“winmgmts:” _& “{impersonationLevel=impersonate}!\\” & strComputer & “\root\cimv2”)).

Un grande grazie alle fonti che hanno permesso di “pacchettizzare” una soluzione rapida per aggirare un banale ostacolo:

Buon lavoro!

Condividi l'articolo con i tuoi contatti:

Pillole

Le pillole sono articoli di veloce lettura dedicati a notizie, script o qualsiasi altra cosa possa essere "divorata e messa in pratica" con poco. Uno spazio del blog riservato ai post "a bruciapelo"!

Non so se si può parlare di una vera e propria nuova versione. Cambia poco rispetto alla precedente, ma stavolta si può scegliere di controllare lo stato di lock out di un utente direttamente proponendolo da riga di comando, così da poter utilizzare lo stesso identico script e clonare facilmente l’operazione pianificata, così da monitorare contemporaneamente più utenti.

Powershell: LockoutAD.ps1, utente a riga di comando

Cosa cambia quindi rispetto al precedente articolo? Presto detto:

#-----------------------------------------------#
#   ACCOUNT DA MONITORARE:                      #
    Param( 
        [Parameter(Position=0, Mandatory=$false, ValueFromPipeline=$true)] 
        [string] $AccountMonitor
    )
#-----------------------------------------------#

Questo, al posto del precedente $AccountMonitor = 'ACCOUNT_AD', permetterà di richiamare lo script in maniera tale da passargli l’account direttamente dal prompt della PowerShell: .\LockoutAD.ps1 ACCOUNT_AD

Chiaramente, per evitare che ci si dimentichi di specificare l’utente, basterà specificare un valore di default che lo script adotterà nel caso in cui non ci siano parametri, qualcosa del tipo:

 if ([string]::IsNullOrEmpty($AccountMonitor)) { $AccountMonitor = 'ACCOUNT_AD' }

così da tutelare una corretta esecuzione del codice. Questa istruzione andrebbe messa chiaramente dopo il catch del parametro da riga di comando, ma prima di lasciar fare la ricerca dell’evento 4771 (o 4740, in base a ciò che si desidera monitorare).

Tutto il resto può rimanere invariato. Se si intende fare un test di funzionamento senza allertare troppi indirizzi di posta elettronica, si potrà clonare la riga del Send-MailMessage assicurandosi di essere unici destinatari (commentando quella che include quindi eventuali CC o BCC), per poi tornare alla normalità quando si è sicuri che tutto fili liscio.

Magari, in una prossima pillola, ti mostrerò come arricchire ulteriormente lo script, prevedendo uno sblocco automatico dell’utenza di dominio bloccata, così che tu possa analizzare con un attimo più di calma cosa è accaduto e nel frattempo l’utente non si accorga di nulla (o quasi).

A proposito di EventLog e PowerShell

Ho modificato il comportamento dello script perché ho avuto la necessità di clonare l’operazione schedulata sul server di dominio così da tenere d’occhio un differente utente. Per poter approfondire il motivo dei lock di quest’ultimo, ho utilizzato PowerShell per filtrare più rapidamente il log degli eventi di sicurezza, generalmente molto nutrito e che mette un attimo in difficoltà la GUI accessibile tramite Visualizzatore degli Eventi. Per questo motivo ho cercato informazioni in merito e trovato alcuni interessanti spunti su serverfault.com/questions/584309/powershell-and-using-get-eventlog.

Nello specifico, ho filtrato direttamente gli eventi 4740 e 4771 protagonisti dello script, includendo inoltre lo specifico nome utente problematico, tramite una semplice query di questo tipo:

Get-EventLog Security 4771,4740

Che, per filtrare esclusivamente un utente, diventerà:

Get-EventLog Security 4740,4771 -after ((get-date).addDays(-1)) | Where-Object {$_.message -match "NOMEUTENTE"}

Permettendoti così di ottenere a video uno storico completo dell’attività dell’utente specifico, anche quando si tratta di tentativi di accesso molto vecchi (dipende poi dalla quantità di log che tiene il server secondo impostazioni del suo amministratore), ignorando quindi il mio -Newest 1 che nello script permette di prendere in esame solo l’ultimo dei tentativi errati (quello in realtà relativo al blocco dell’account in LDAP).

Buon lavoro!

immagine featured: PowerShell Magazine

Condividi l'articolo con i tuoi contatti:

sourcecode-vbscriptSai già come funziona, di tanto in tanto apro il cassetto degli attrezzi, utilizzo uno script e poi penso che potrebbe essere interessante per qualcun altro sul web, quindi decido di condividerlo con te che sei dall’altra parte del monitor e che stai forse svolgendo un mestiere simile al mio.

Qualche tempo fa ho rimaneggiato un po’ di codice per realizzare un piccolo VBScript che fosse in grado di ritoccare la descrizione di un PC da remoto, senza che l’utente si accorga di nulla, collegandomi in maniera amministrativa grazie alla rete di dominio.

Da un’idea e realizzazione originale di Rob Dunn (il suo sito web non esiste più, nda), il codice qui di seguito mostra un popup a video che legge l’attuale descrizione di un PC (raggiunto tramite hostname o IP) e permette contestualmente di modificarla.

' PC Description Changer per Windows Xp+
' GSolone 2015 v 0.3
' Basato su script originale di Rob.Dunn (www.theitoolbox.com)
' Ultima modifica 17122015
'
' - accetta da prompt dei comandi il nome macchina (o IP) da raggiungere (es. PCDescription.vbs 127.0.0.1)
' - Windows XP e 2003 richiedono un riavvio macchina per poter mostrare poi la description corretta.
' - il servizio di remote registry deve essere attivo e occorre anche avere le permission WMI)
' - lo script tronca oltre i 48 caratteri forniti come testo della descrizione PC
'
' LO SCRIPT VA ESEGUITO COME AMMINISTRATORE MACCHINA O DI DOMINIO!

Dim strDescription, strComputer, reg, objRegistry
Dim ret, msg, ValueName 

Const HKLM = &H80000002

if WScript.Arguments.Count = 0 then
    'Richiesta IP o hostname macchina da modificare
    strComputer = InputBox("PC Description Changer (Win Xp +)" & vbCR & vbCR & "VA ESEGUITO COME ADMIN LOCALI O DI DOMINIO!" & vbCR & vbCR & "Inserisci il nome macchina o indirizzo IP da raggiungere (vuoto o clic su Annulla per uscire dallo script)" & vbCR, "PC Description Changer", "W7-TEST")
else
    'Se l'indirizzo IP / Hostname mi è stato passato da riga di comando, posso procedere direttamente
    strComputer = Wscript.Arguments(0)
end if

if strComputer = "" then wscript.quit

on error resume next

Set reg = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")

if err.number <> 0 then 
  msgbox "Problemi di connessione al database WMI di " & strComputer & ".  Verifica che il PC sia acceso e che tu abbia tutti i permessi per poter effettuare l'operazione",16,"Errore di connessione a '" & strComputer & "'" 
  wscript.quit  
end if

on error goto 0 

Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2").ExecQuery("Select Description FROM Win32_OperatingSystem")


For Each object In objRegistry
    strDescription = object.Description 
Next 

value = inputbox("Inserisci una nuova descrizione per '" & strComputer & "' (o fai clic su Annulla per terminare lo script):","PC Description Changer",strDescription)

If value = strDescription then wscript.quit

key = "SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters"
ValueName = "srvcomment"

If Len(Value) > 48 Then Value = Left(Value, 48)
ret = reg.SetStringValue(HKLM, key, ValueName, value)

if ret <> 0 then msgbox "Aggiornamento remoto fallito."

All’interno del codice c’è anche qualche rapida istruzione (in parte riproposta a video) per guidarti all’uso o a capire cosa può andare storto. Ricorda che il servizio di Remote Registry deve essere attivo sulla macchina di destinazione (e l’account che lancia lo script deve avere i permessi per amministrarla, vale quindi lanciarlo da un prompt dei comandi elevato), altrimenti si incorre in popup di errore come questo:

VBS: cambiare la descrizione di un PC da remoto

Tutti i test sono stati condotti su Windows 7, 8.1 e 10. In passato l’ho usato anche per macchine XP senza battere ciglio, spero però per te che tu non abbia più quel SO in giro ;-)

Per dubbi o chiarimenti, citofonare nell’area commenti.

Cheers.

Condividi l'articolo con i tuoi contatti:

Powershell_512px-GWallFaccio riferimento a un vecchio articolo datato 2014, nel quale vi parlavo di uno script PS1 che avevo lasciato su un Domain Controller della rete per verificare l’utilizzo di una password errata per un determinato account di dominio. Quello script mi è tornato utile ancora una volta e oggi vi propongo il suo ultimo aggiornamento, in grado di monitorare il blocco dell’account di Active Directory, con conseguente mail di allerta a 3 diversi indirizzi di posta (mio e di due colleghi, in CC).

L’originale è ancora disponibile:

Powershell: Account di dominio bloccato o utilizzo di password errata? Mandami una mail con l’evento!

Cosa è cambiato?

L’ID dell’evento sotto monitor, come prima cosa: si tratta del 4740 e l’operazione pianificata si crea ancora alla stessa identica maniera, con l’eccezione del richiamo al prompt di PowerShell che ora utilizzo in maniera classica, passandogli poi parametri da riga di comando che vanno a richiamare il nuovo script:

Nel nuovo script è poi cambiato il testo della segnalazione che arriverà a mezzo mail, la parte commentata (per darle un aspetto migliore, nulla più) e il modo di inviare la mail ai destinatari, che mi permette così di utilizzare anche il -CC e la priorità (-Priority). Già messo alla prova, non fallisce un colpo, permettendo di diventare assolutamente reattivi nei confronti del monitorato “ACCOUNT_AD” (da modificare con l’utente che volete realmente tenere sotto controllo).

Come già detto, l’operazione pianificata sul server riguarderà l’evento 4740, il quale lancerà PowerShell passandogli come parametro lo script che nel frattempo avrete salvato in una cartella sul server (nel mio caso, C:\Script):

Ricordate che, in tutto questo, sarà necessario che la macchina sulla quale farete girare il file PS1 abbia la policy di esecuzione script non firmati, basterà lanciare (da PowerShell):

Set-ExecutionPolicy Unrestricted

e confermare la scelta quando vi verrà chiesto a video.

Con una ulteriore modifica, si potrebbe chiedere allo script di sbloccarlo automaticamente dopo un certo intervallo di tempo. Non l’ho volutamente ancora sviluppato perché non è la richiesta ricevuta, ma nessuno impedisce a voi di completare il quadro (e poi magari toccherà anche a me, probabilmente vi basterà attendere) :-)

Condividi l'articolo con i tuoi contatti:

AutomatorJacob Salmela ha pubblicato un codice tanto banale quanto perfetto, lo scorso 12 marzo, per permettere ad Automator di trasformare un documento di Word (DOCX) in un file PDF con un paio di clic (tasto destro sul file interessato → Servizi → Convert DOCX to PDF). Una modifica a quel codice permette inoltre di scavalcare (la malaugurata tanto quanto voluta) scelta di cancellare il file sorgente una volta ottenuto il PDF. Il codice modificato sarà il seguente:

#!/bin/bash
# Jacob Salmela 2016-03-12
# Gioxx 2016-03-22
# Convert annoying DOCX into PDFs with a right-click
# Run this as an Automator Service

###### SCRIPT #######
for f in "$@"
do
 # Get the full file PATH without the extension
 filepathWithoutExtension="${f%.*}"
 # Convert the DOCX to HTML, which cupsfilter knows how to turn into a PDF
 textutil -convert html -output "$filepathWithoutExtension.html" "$f"
 # Convert the file into a PDF
 cupsfilter "$filepathWithoutExtension.html" > "$filepathWithoutExtension.pdf"
 # Remove the temporary HTML file, leaving the original DOCX and the new PDF
 rm "$filepathWithoutExtension.html" >/dev/null
done

La differenza è esclusivamente nell’ultimo Remove (rm), che nella modifica esclude il file originale ($f), il DOCX, diventando quindi:

# Remove the temporary HTML file, leaving the original DOCX and the new PDF
 rm "$filepathWithoutExtension.html" >/dev/null

Tutto il resto rimane invariato proprio perché già funzionante. Ho creato una copia del file di Workflow che potete scaricare e installare rapidamente, la trovate all’indirizzo app.box.com/s/jzits3oxyyuptqtmhkkrrvhp8th9wmp6.

Scompattate il file sul vostro OS X, quindi con un doppio clic chiedete al sistema di installarlo:

OS X: convertire un DOCX in PDF con due clic

Da questo momento, potrete convertire rapidamente un vostro documento Word in PDF, semplicemente seguendo la procedura sopra indicata (tasto destro sul file interessato → Servizi → Convert DOCX to PDF).

E se volessi rimuoverlo?

Pensate che il servizio non serva più e che quella voce sia particolarmente sgradita nel vostro menu Servizi? Nessun problema, si fa sempre in tempo a rimuoverlo.

  • In una finestra di Finder, premete ⌘ ⇧ G (apre una cartella specifica).
  • Inserite “~/Library/Services” (senza le virgolette).
  • Cercate il file relativo al servizio installato non più desiderato.
  • Cancellate il file (o trascinatelo nel cestino)

Il servizio non sarà più disponibile :-)

Il mio personale grazie a Jacob per l’ottimo lavoro, non ci avevo pensato e ho spesso utilizzato il Terminale per eseguire la stessa operazione o Word stesso per salvare (da Salva con nome) il file in formato PDF. Fortunatamente non si finisce mai di imparare!

Condividi l'articolo con i tuoi contatti: