WSH Shell : Afficher les URL d`une machine distante

Transcription

WSH Shell : Afficher les URL d`une machine distante
glsft.free.fr
WSH Shell : Afficher les URL d'une machine distante
Soumis par Gilles LAURENT
26-08-2008
WSH Shell : Afficher les URL des instances Internet Explorer en cours d'exécution sur une machine distante
Une question d'un usager sur le Forum Scripting (Fr) était de savoir s'il était possible de déterminer par script les URL
des instances Internet Explorer en cours d'exécution sur une machine distante. J'ai tout d'abord pensé, à tord, que le
simple fait d'utiliser l'outil PSExec de Windows Sysinternals pour exécuter un script VBScript distant suffirait pour
accomplir cette tâche en s'inspirant du précédent article WSH Shell : Afficher les URL. Et bien NON ! Pour la bonne et
simple raison que l'outil PSExec n'est pas en mesure d'exécuter à distance un outil ou un script au sein d'une session
utilisateur connecté sur une machine distante. Cela n'est pas grave car il y a quelques temps maintenant, j'avais
developpé l'outil RunAsLoggedOnUser permettant de réaliser cette tâche (Vous pouvez retrouver l'article concernant cet
outil en suivant ce lien). J'ai donc rapidement maquetté une solution, ce qui m'a conduit à mettre à jour l'outil
RunAsLoggedOnUser pour, entre autre, ajouter le support de la redirection des flux puis à créer un module externe
compatible avec la console WSH Shell. C'est cette solution que je vous présente ici et qui se compose de l'outillage et
pré requis suivants :
1- Sur la machine d'administration :
- De la classe VBScript _wshRemoteIExplore.inc (module externe WSH Shell)
Ce module est à déposer dans le sous-dossier Include de la console WSH Shell
- De l'outil PSExec de Windows Sysinternals
- De l'outil RunAsLoggedOnUser de moi-même ;-)
Il est absolument nécessaire d'utiliser la version supérieure ou égale à la v1.0.0.3
- Du composant COM DynaWrap (version étendue obligatoire)
Ce composant a besoin d'être inscrit dans le registre via la commande regsvr32 sur la machine d'administration. Il est à
noter que cette opération est automatiquement réalisée depuis la version v1.0.0.9 du setup WSH Shell si le
composant DynaWrap - DynaCall Wrapper a été sélectionné dans la liste des composants additionnels à installer)
Note : Le composant COM DynaWrap est utilisé pour invoquer les API Win32 suivantes :
- NetApiBufferFree
- NetWkstaGetInfo
- PathFindOnPathW
2- Sur la machine distante :
- Du script VBScript IExplore.vbs (à installer par défaut à la racine de la partition C:\)
La propriété RemoteScriptFolder de la classe wshRemoteIExplore permet de modifier ce chemin par défaut. Ce script
pourra, par exemple, être installé dans le dossier partagé netlogon d'un contrôleur de domaine pour les postes membres
d'un domaine. Dans ce cas, il faudra utiliser la syntaxe d'expansion retardée des variables d'environnement compatible
avec l'outil RunAsLoggedOnUser, c'est à dire :
WSH D:\Test> oRemoteIE.RemoteScriptFolder="{logonserver}\netlogon"
- Du composant COM DynaWrap (version étendue obligatoire)
Il est facilement possible de s'affranchir de ce pré requis si uniquement les URL doivent être affichées. Le script
IExplore.vbs devra dans ce cas être adapté en conséquence
Note : Le composant COM Dynawrap est utilisé pour invoquer l'API Win32 suivante :
- GetWindowThreadProcessId
Important : Comme le soulignait à juste titre Jacques Barathon [MS] dans ce fil de discussion, j'attire également votre
attention sur le risque d'illégalité de l'utilisation de cette solution si les utilisateurs finaux ne sont pas prévenus que leur
navigation Internet est susceptible d'être surveillée. Cette solution (scripts VBScript ainsi que les outils personnels
développés qui l'accompagne) est destinée à un usage à but purement éducatif et non à un usage dans le cadre d'une
utilisation illégale.
Bon, le décor étant maintenant planté, il est temps de démarrer une console WSH Shell pour tester ce nouveau module
externe ! Les commentaires se font au fil de l'eau en ligne de commandes dans la
console.Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. Tous droits réservés.
_ _ _ ___ _ _ ___ _
_ _
| | | |/ __>| | | / __>| |_ ___ | || |
| | | |\__ \| | \__ \| . |/ ._>| || |
|__/_/ <___/|_|_| <___/|_|_|\___.|_||_|
http://glsft.free.fr
Propulsé par Joomla!
Généré: 16 February, 2017, 19:51
glsft.free.fr
Windows Script Host (WSH) Shell v1.0.0.9 starting ...
Registering components ...
Loading external modules ...
Loading _wshAdsi.inc ...
Loading _wshCalendar.inc ...
Loading _wshCodeSyntaxing.inc ...
Loading _wshComputerToolbox.inc ...
Loading _wshCultures.inc ...
Loading _wshFtp.inc ...
Loading _wshIExplore.inc ...
Loading _wshIni.inc ...
Loading _wshModuleManager.inc ...
Loading _wshRemoteIExplore.inc ...
Loading _wshTaskView.inc ...
Loading _wshWmi.inc ...
Loading profiles ...
Loading D:\Users\Dev\Copyright\WSH\Release\WSHShell_Profile.inc ...
Loading D:\Documents and Settings\Gilles\Mes documents\WSH Shell\WSHShell_P...
Welcome ...
It's 25/08/2008 18:46:48 and WSH Shell is up !
Ready.
WSH D:\Test> ' notre nouveau module est bien présent dans la liste des modules
WSH D:\Test> ' automatiquement chargés. Il ne reste plus, comme d'habitude, à
WSH D:\Test> ' créer une instance pour en bénéficier
WSH D:\Test> Set oRemoteIE=New wshRemoteIExplore
WSH D:\Test>
WSH D:\Test> ' détermination des membres (méthodes et propriétés)
WSH D:\Test> gm(oRemoteIE)
Category Name
-------- ---Function CheckPrerequisites ()
Function GetRemoteIERunningInstances (strComputer)
Function IsUserLoggedIn (strComputer)
Property OptionalToolsFolder
Property RemoteScriptFolder
Property Verbose
Property Version
WSH D:\Test> ' la méthode "CheckPrerequisites ()" permet de vérifier que les
WSH D:\Test> ' pré requis sont bien présent dans un dossier référencé par la
WSH D:\Test> ' variable d'environnement Path ou alors dans le dossier pointé
WSH D:\Test> ' par la propriété OptionalToolsFolder
WSH D:\Test> ' les pré requis sont les deux outils suivants :
WSH D:\Test> ' - PsExec de Windows Sysinternals
WSH D:\Test> ' - RunAsLoggedOnUser >= 1.0.0.3 disponible sur mon site
WSH D:\Test>
WSH D:\Test> ' vérification des pré requis
WSH D:\Test> echo CStr (oRemoteIE.CheckPrerequisites ())
Checking prerequisites ...
PSExec.exe
: Faux
RunAsLoggedOnUser.exe : Faux
Operation completed successfully
Faux
WSH D:\Test> ' les deux outils ne sont pas installés ou non présents dans l'un
WSH D:\Test> ' des dossiers référencé par la variable d'environnement Path
WSH D:\Test> ' en fait, j'ai installé ces deux outils dans le dossier "D:\Test"
WSH D:\Test> oRemoteIE.OptionalToolsFolder = "D:\Test"
http://glsft.free.fr
Propulsé par Joomla!
Généré: 16 February, 2017, 19:51
glsft.free.fr
Checking Tools Folder ...
Tools folder exists on this machine : D:\TEST
Operation completed successfully
WSH D:\Test> ' ok, le dossier spécifié existe bien sur ma machine locale
WSH D:\Test> ' nouvelle vérification des pré requis
WSH D:\Test> echo CStr (oRemoteIE.CheckPrerequisites ())
Checking prerequisites ...
PSExec.exe
: Vrai
RunAsLoggedOnUser.exe : Vrai
Operation completed successfully
Vrai
WSH D:\Test> ' tout semble en ordre au niveau de l'outillage nécessaire
WSH D:\Test> ' une autre étape consiste à s'assurer qu'un utilisateur est bien
WSH D:\Test> ' connecté sur la machine distante
WSH D:\Test> ' pour cela il suffit d'utiliser la méthode "IsUserLoggedIn" en
WSH D:\Test> ' spécifiant comme paramètre le nom NetBIOS ou DNS de la machine
WSH D:\Test> ' distante
WSH D:\Test> echo CStr (oRemoteIE.IsUserLoggedIn ("\\homem500"))
Trying to connect to \\HOMEM500 ...
Number of logged on users (including service accounts) : 2
At least on user is logged in to \\HOMEM500
Operation completed successfully
Vrai
WSH D:\Test> ' au moins un utilisateur semble être connecté sur la machine
WSH D:\Test> ' distance HOMEM500
WSH D:\Test> ' Note: Les comptes de service sont également comptabilisés !
WSH D:\Test>
WSH D:\Test> ' le script VBScript distant doit être présent dans un dossier
WSH D:\Test> ' de la machine distante. Ce script VBScript porte le nom :
WSH D:\Test> ' IExplore.vbs. Par défaut, il doit être présent à la racine de
WSH D:\Test> ' la partition C:\. Ce dossier par défaut peut être modifié via
WSH D:\Test> ' la propriété "RemoteScriptFolder"
WSH D:\Test> ' affichage du dossier distant défini par défaut
WSH D:\Test> echo oRemoteIE.RemoteScriptFolder
C:\
WSH D:\Test> ' lecture des URL Internet Explorer (ici la version IE7)
WSH D:\Test> ' - deux onglets dans une instance IE7
WSH D:\Test> ' - un seul onglet dans une autre instance IE7
WSH D:\Test> arrURL=oRemoteIE.GetRemoteIERunningInstances ("\\homem500")
Checking prerequisites ...
PSExec.exe
: Vrai
RunAsLoggedOnUser.exe : Vrai
Operation completed successfully
Creating temporary file ...
Running remote command ...
Checking result ...
Reading remote URL ...
Operation completed successfully
WSH D:\Test> ' Tout est "successfully" ;-)
WSH D:\Test> ' combien d'URL utilise l'utilisateur sur la machine distante ?
WSH D:\Test> echo UBound (arrURL)
3
WSH D:\Test> ' l'utilisateur connecté sur la machine distante HOMEM500 utilise
WSH D:\Test> ' actuellement trois URL
WSH D:\Test> ' mais quelles sont ces URL consultées ?
WSH D:\Test> ' affichage formaté des instances IE
WSH D:\Test> ft arrURL,"Id","","*"
Id Name
URL
-- -----2568 iexplore.exe http://glsft.free.fr/
3512 iexplore.exe http://fr.msn.com/
3512 iexplore.exe http://www.google.fr/
WSH D:\Test> ' Enjoy !
http://glsft.free.fr
Propulsé par Joomla!
Généré: 16 February, 2017, 19:51
glsft.free.fr
Tip_1 : Fixer la propriété Verbose à False désactive le mode verbeux ;-)
Vous trouverez ci-dessous le listing du module externe _wshRemoteIExplore.inc de la console WSH Shell ainsi que
le listing du script VBScript IExplore.vbs à déposer celui-ci sur la machine distante.
Listing 1 : _wshRemoteIExplore.inc
-'
- ' Windows Script Host (WSH) Shell
- ' (c) 2008 Gilles LAURENT
- ' wshRemoteIExplore Class v1.0.0.1
-'
- Option Explicit
- ' spécification des objets COM requis pour exécuter ce module externe
- ' un message d'erreur s'affichera lors du chargement du module externe
- ' si les pré requis ne sont pas vérifiés et la classe ne sera pas chargée
- ' en mémoire donc ne pourra être instanciée
- shell.Require "DynamicWrapper"
- Class WSHRemoteIExplore
- ' =========================
- ' == PRIVATE PROPERTIES
- ' =========================
- Private m_oFs, m_oRe, m_oDyn, m_oSh
- Private m_strToolsFolder, m_strScriptFolder, m_strRALUPath, m_strPSEPath
- Private m_dwToolsPtr
- Private m_bVerbose
- ' =========================
- ' == PUBLIC PROPERTIES
- ' =========================
- Public Property Get OptionalToolsFolder ()
OptionalToolsFolder = m_strToolsFolder
- End Property
- Public Property Let OptionalToolsFolder (strToolsFolder)
' déclaration des variables
Dim oFolder
If Not IsNull (strToolsFolder) Then
' vérification de l'existance du dossier contenant les outils
PrintMessage "Checking Tools Folder ..." & Chr (2)
Set oFolder = m_oFs.GetFolder (strToolsFolder)
' le dossier existe
' lecture du chemin court
m_strToolsFolder = oFolder.ShortPath
PrintMessage "Tools folder exists on this machine : " & UCase (m_strToolsFolder) & Chr (2)
' libération de l'objet
Set oFolder = Nothing
Else
' le dossier n'est pas spécifié
m_strToolsFolder = Null
End If
' détermination de l'adresse de la chaine de caractères
m_dwToolsPtr = m_oDyn.GetBSTRAddr (m_strToolsFolder)
' traitement achevé avec succès
PrintMessage "Operation completed successfully" & Chr (2)
- End Property
- Public Property Get RemoteScriptFolder ()
RemoteScriptFolder = m_strScriptFolder
- End Property
- Public Property Let RemoteScriptFolder (strScriptFolder)
PrintMessage "Remote script folder set to " & UCase (strScriptFolder) & Chr (2)
m_strScriptFolder = strScriptFolder
' traitement achevé avec succès
PrintMessage "Operation completed successfully" & Chr (2)
http://glsft.free.fr
Propulsé par Joomla!
Généré: 16 February, 2017, 19:51
glsft.free.fr
-
End Property
Public Property Get Verbose ()
Verbose = m_bVerbose
End Property
Public Property Let Verbose (bValue)
m_bVerbose = CBool (bValue)
End Property
Public Property Get Version ()
m_oRe.Pattern="\r\n\'.+?[vV]((\d+\.?){3}(\.\d+)?)\r\n"
Version = m_oRe.Execute (m_oFs.OpenTextFile (shell.Path & "\Include\_" & TypeName (Me) & ".inc", 1, False).ReadAll ())(
Matches (0)
- End Property
- ' =========================
- ' == PRIVATE MEMBERS
- ' =========================
- Private Sub Class_Initialize ()
' initialisation des objets
Set m_oDyn = CreateObject ("DynamicWrapper")
Set m_oFs = CreateObject ("Scripting.FileSystemObject")
Set m_oSh = CreateObject ("WScript.Shell")
Set m_oRe = New RegExp
' initialisation des variables
m_bVerbose = True
m_strToolsFolder = Null
m_strScriptFolder = "C:\"
m_dwToolsPtr = m_oDyn.GetBSTRAddr (m_strToolsFolder)
' déclaration des API Win32 (prototypes)
m_oDyn.Register "shlwapi.dll", "PathFindOnPathW", "f=s", "r=b", "i=ll"
m_oDyn.Register "netapi32.dll", "NetApiBufferFree", "f=s", "r=l", "i=l"
m_oDyn.Register "netapi32.dll", "NetWkstaGetInfo", "f=s", "r=l","i=lll"
' définition des propriétés de l'expression régulière
m_oRe.IgnoreCase = True
m_oRe.Multiline = False
m_oRe.Global = True
- End Sub
- Private Sub Class_Terminate ()
' libération des objets
Set m_oRe = Nothing
Set m_oSh = Nothing
Set m_oFs = Nothing
Set m_oDyn = Nothing
- End Sub
- Private Sub PrintMessage (str)
' le message s'affiche uniquement en mode verbeux
If Verbose Then WScript.Echo str
- End Sub
- ' =========================
- ' == PUBLIC MEMBERS
- ' =========================
- Public Function CheckPrerequisites ()
' déclaration des variables
Dim bRet(1)
Dim strFileName
' vérification de la présence des pré requis
PrintMessage "Checking prerequisites ..." & Chr (2)
strFileName=Left("PSExec.exe" & String(260,0), 260)
bRet(0) = m_oDyn.PathFindOnPathW (m_oDyn.GetBSTRAddr(strFileName), m_oDyn.GetVariantAddr (m_dwToolsPtr))
PrintMessage "PSExec.exe
: " & CStr (bRet(0)) & Chr (2)
' sauvegarde du chemin complet de l'outil PSExec.exe
m_strPSEPath = Left(strFileName, InStr(strFileName, Chr(0)) - 1)
strFileName=Left("RunAsLoggedOnUser.exe" & String(260,0), 260)
bRet(1) = m_oDyn.PathFindOnPathW (m_oDyn.GetBSTRAddr(strFileName), m_oDyn.GetVariantAddr (m_dwToolsPtr))
PrintMessage "RunAsLoggedOnUser.exe : " & CStr (bRet(1)) & Chr (2)
http://glsft.free.fr
Propulsé par Joomla!
Généré: 16 February, 2017, 19:51
glsft.free.fr
' sauvegarde du chemin complet de l'outil RunAsLoggedOnUser.exe
m_strRALUPath = Left(strFileName, InStr(strFileName, Chr(0)) - 1)
' traitement achevé avec succès
PrintMessage "Operation completed successfully" & Chr (2)
' retour du résultat de l'opération
CheckPrerequisites = bRet(0) And bRet(1)
- End Function
- Public Function GetRemoteIERunningInstances (strComputer)
' déclaration des variables
Dim strTempFileName, strCmd
Dim arrContent
' vérification de la présence des pré requis
If CheckPrerequisites () = True Then
' création d'un fichier temporaire
PrintMessage "Creating temporary file ..." & Chr (2)
strTempFileName = m_oFs.GetSpecialFolder (2) & "\" & m_oFs.GetTempName ()
' préparation de la commande
strCmd = "%COMSPEC% /c " & m_strPSEPath & " " & strComputer & " -accepteula -s -c " & m_strRALUPath & " -hide
cmd " & Chr(34) & "cscript.exe //nologo " & m_strScriptFolder & "\IExplore.vbs" & Chr(34) & "2>nul >" & strTempFileName
' exécution de la commande distante
' la méthode Exec ne semble pas fonctionner avec l'outil psexec :-(
PrintMessage "Running remote command ..." & Chr (2)
m_oSh.Run strCmd, 0, True
' vérification du résultat de l'opération
PrintMessage "Checking result ..." & Chr(2)
' le fichier peut être vide sur la machine distante est inaccessible
' il est donc nécessaire de gérer les erreurs
On Error Resume Next
arrContent = Shell.GetFileContent (strTempFileName)
On Error Goto 0
' le fichier ne doit pas être vide !
If IsArray (arrContent) Then
' vérification de la présence du header
If arrContent(0) = "Id,Name,URL" Then
' lecture des url
PrintMessage "Reading remote URL ..." & Chr (2)
GetRemoteIERunningInstances = Shell.StringToArray (Replace (Shell.ArrayToString (arrContent), ",", Shell.strTable
)
' traitement achevé avec succès
PrintMessage "Operation completed successfully" & Chr (2)
Else
' une erreur est survenue
WScript.Echo ":: An error occurred" & Chr (1) & " :: Remote process failed to execute"
End If
Else
' une erreur est survenue
WScript.Echo ":: An error occurred" & Chr (1) & " :: Temporary file is empty !"
End If
' suppression du fichier temporaire
If m_oFs.FileExists (strTempFileName) Then m_oFs.DeleteFile strTempFileName, True
Else
' les pré requis ne sont pas vérifiés
' Impossible d'exécuter l'opération requise
Err.Raise 17
End If
- End Function
- Public Function IsUserLoggedIn (strComputer)
' déclaration des variables
Dim bUserLoggedIn: bUserLoggedIn = False
Dim lRet, lBufferAddr, lBufferPtr, lNbLoggedOnUsers
' récupération des informations de niveau 102
' la structure WKSTA_INFO_102 est allouée par le système
PrintMessage "Trying to connect to " & UCase (strComputer) & " ..." & Chr (2)
lRet = m_oDyn.NetWkstaGetInfo (m_oDyn.GetBSTRAddr (strComputer), 102, m_oDyn.GetVariantAddr (lBufferAddr))
http://glsft.free.fr
Propulsé par Joomla!
Généré: 16 February, 2017, 19:51
glsft.free.fr
' vérification du résultat de l'opération
If lRet = 0 Then
' l'opération a réussi
' récupération du pointeur sur la structure WKSTA_INFO_102 (LPBYTE *)
lBufferPtr = m_oDyn.GetMemInBSTRAddr(m_oDyn.GetVariantAddr (lBufferAddr), 0, 4)
' détermination du nombre d'utilisateur connecté sur la machine distante
lNbLoggedOnUsers = m_oDyn.GetMemInBSTRAddr (lBufferPtr, 24, 4)
PrintMessage "Number of logged on users (including service accounts) : " & lNbLoggedOnUsers & Chr (2)
' évaluation du nombre d'utilisateur connecté
If lNbLoggedOnUsers > 0 Then
' au moins un utilisateur est connecté sur la machine distante
PrintMessage "At least on user is logged in to " & UCase (strComputer) & Chr (2)
bUserLoggedIn = True
Else
' aucun utilisateur connecté sur la machine distante
PrintMessage "No user is logged in to " & UCase (strComputerName)
End If
' libération du buffer alloué par le système
m_oDyn.NetApiBufferFree (lBufferAddr)
Else
' une erreur est survenue
WScript.Echo ":: An error occurred (" & lRet & ")" & Chr (1) & " :: " & m_oDyn.FormatMessage (lRet)
End If
' traitement achevé avec succès
PrintMessage "Operation completed successfully" & Chr (2)
' retour du résultat de l'opération
IsUserLoggedIn = bUserLoggedIn
- End Function
- End Class
Listing 2 : IExplore.vbs
- Option Explicit
- ' déclaration des variables
- Dim oDyn, oApp, oWindow, oProc
- Dim dwPid: dwPid=CLng(0)
- ' initialisation des objets
- Set oDyn=CreateObject("DynamicWrapper")
- Set oApp=CreateObject("Shell.Application")
- ' déclaration des API Win32 (prototypes)
- oDyn.Register "User32.dll", "GetWindowThreadProcessId", "f=s", "r=l", "i=hl"
- ' écriture du header dans le flux stdout
- WScript.Echo "Id,Name,URL"
- ' énumération des instances Explorer et Internet Explorer
- For Each oWindow In oApp.windows
- ' détermination du pid du processus
- oDyn.GetWindowThreadProcessId oWindow.HWND, oDyn.GetVariantAddr(dwPid)
- ' détermination du nom du processus
- Set oProc = GetObject("winmgmts:/root/cimv2:Win32_Process.Handle='" & dwPid & "'")
- ' écriture des informations dans le flux stdout
- WScript.Echo oProc.ProcessId & "," & oProc.Name & "," & oWindow.LocationURL
- Next
http://glsft.free.fr
Propulsé par Joomla!
Généré: 16 February, 2017, 19:51

Documents pareils