Версия для печати темы

Нажмите сюда для просмотра этой темы в оригинальном формате

WinCity.Ru _ Программирование _ VBS нужна помощь по написанию скрипта

Автор: Theridiidae Четверг, 08 Апреля 2010, 16:35

В общем есть проблема, в удаленном расшаривании(развертывании) дисков.
Раньше было все просто в GPO для пользователей в сценарии запуска стояла
сточка net use z: \server00downloads$. Как говориться песец подкрался быстро и неожиданно появился в офисе Win7x64. Не знаю точно какие параметры команды NET у Win7x86 но Win7x64 команду net use z: \server00downloads$ не проглатывает, ругается.
Не когда не писал на vbs но по видимому придется начать =)
На одном из форумов пользователем dimich22 был выложен достаточно объемный листинг файлы по прежнему прикреплять не могу да простят меня администраторы выложу листинг тут.

Скрипт как я понял подключает диски в зависимости от расположения пользователя в той или иной группе.(В общем шикарнейшая вещ)
Ну вот проблема не могу разобраться почему не работает =\

Цитата
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
On Error Resume Next
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Define Variables and Constants
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

Dim objFileSys
Dim objIntExplorer
Dim objWshNetwork
Dim objWshShell
Dim strDomain 'Domain of the user
Dim strHomePage 'Homepage to be set for user (Домашняя страница пользователя)
Dim strLogonPath 'Path to location from where the script is running (Путь к месту расположению скрипта)
Dim strOSProdType 'OS Product type (WinNT, LanmanNT, ServerNT)
Dim strWorkstation 'Local Computer Name (Локальное имя компьютера)
Dim strUserGroups 'List of groups the user is a meber of (Список групп к которым пренадлежит пользователь)
Dim intCounter 'General counter (Общий счетчик)

Const UseNTServer = 0 'Sets whether this script runs when logging on locally (Нужно ли запускать этот скрипт локально)
'to Windows Servers.
'Values are: 1 (Yes) OR 0 (No)

Const FileSrv1 = "\w2kserver"
Const FileSrv2 = "\calculator2"

'Initialize common scripting objects (Инициализация общих объектов)
Set objFileSys = CreateObject( "Scripting.FileSystemObject" )
Set objWshNetwork = CreateObject( "WScript.Network" )
Set objWshShell = CreateObject( "WScript.Shell" )

'Pause script until user is fully logged on (applicable only to Win 9x or ME) (Приостановить выполнение сценария пока пользователь полность не войдет в систему (только для  Win 9x или ME)
'This will timeout after 10 seconds (Время ожидания 10 секунд)
strUser = ""
intCounter = 0
Do
strUserID = objWshNetwork.Username
intCounter = intCounter + 1
Wscript.Sleep 500
Loop Until strUserID <> "" OR intCounter > 20

'Check for error getting username (Проверить ошибки, получить имя пользователя)
If strUserID = "" Then
objWshShell.Popup "Logon script failed - Contact the Helpdesk @ x 345", , _
"Logon script", 48
Call Cleanup
End If

'Gather some basic system info (Сбор базовой информации о системе)
Call GetSystemInfo

If IsTerminalServerSession <> True Then
'Exit if we are logging on locally to a server and the script is set to NOT run on servers (Выйти если мы вошли на локальный сервер с установленным сценарием не запускать на серверах)
IF UseNTServer = 0 AND (strOSProdType = "LanmanNT" OR strOSProdType = "ServerNT") Then
objWshShell.Popup "Windows Server - Exiting Logon Script!", 10, _
"Logon to " & strDomain, 16
Call CleanUp
End if
End If

'Get group memberships (Получит членство в группах)
strUserGroups = ""
Call GetLocalGroupMembership
Call GetGlobalGroupMembership

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' This section performs actions based on group membership (В этом разделе совершает действия, на основе членства в группе)
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If InGroup( "Бухгалтерия" ) Then
MapDrv "P:", FileSrv1 & "buh$","Папка для бухгалтерии"
MapDrv "P:", FileSrv1 & "buh$","Папка для бухгалтерии"
End If

If InGroup( "Администрация" ) Then
MapDrv "P:", FileSrv1 & "ruk$","Папка для администрации"
MapDrv "P:", FileSrv1 & "ruk$","Папка для администрации"
End If

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' End section
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Sub: MapDrive
' Purpose: Map a drive to a shared folder
' Input:
' strDrive Drive letter to which share is mapped
' strServer Name of server that hosts the share
' strShare Share name
' Output:
' Usage:
' Call MapDrive ("P:", "w2kserver", "tai$")
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function MapDrv(DrvLet, UNCPath, DrvName)

Dim objFSO, oShell ' Object variable

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objoShell = CreateObject("Shell.Application")

On Error Resume Next

If objFSO.DriveExists(DrvLet) Then
objWshNetwork.RemoveNetworkDrive DrvLet, true, true
End If

objWshNetwork.MapNetworkDrive DrvLet, UNCPath
objoShell.NameSpace(DrvLet).Self.Name = DrvName

End Function

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Sub: GetLocalGroupMembership
' Purpose: Gather all local groups the current user belongs to
' Input:
' Output: Local group names are added to strUserGroups
' Usage: Call GetLocalGroupMembership
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub GetLocalGroupMembership

On Error Resume Next

Dim colGroups 'Collection of groups on the local system (Коллекция групп на локальном компьютере)
Dim objGroup 'Object reference to individual groups (Ссылка на объект для отдельных групп)
Dim objUser 'Object reference to individual group member (Ссылка на объект для отдельных членов группы)

'Verify system is not Windows 9x or ME (Убедитесь, система не Windows 9x или ME)
If objWshShell.ExpandEnvironmentStrings( "%OS%" ) = "Windows_NT" Then
'Connect to local system (Connect to local system)
Set colGroups = GetObject( "WinNT://" & strWorkstation )
colGroups.Filter = Array( "group" )
'Process each group (Процесс каждой группы)
For Each objGroup In colGroups
'Process each user in group (Процесс каждого пользователя в группе)
For Each objUser in objGroup.Members
'Check if current user belongs to group being processed (Проверить, если текущий пользователь принадлежит к группе обрабатываются)
If LCase( objUser.Name ) = LCase( strUserID ) Then
'Add group name to list (Добавить название группы к списку)
strUserGroups = strUserGroups & objGroup.Name & ","
End If
Next
Next
Set colGroups = Nothing
End If

End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Sub: GetGlobalGroupMembership
' Purpose: Gather all global groups the current user belongs to
' Input:
' Output: Global group names are added to strUserGroups
' Usage: Call GetGlobalGroupMembership
' Notes: Use WinNT connection method to be backwards
' compatible with NT 4 domains
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub GetGlobalGroupMembership

On Error Resume Next

Dim objNameSpace
Dim objUser

Const ADS_READONLY_SERVER = 4

Set objNameSpace = GetObject( "WinNT:" )
'Use the OpenDSObject method with the ADS_READONLY_SERVER (Используйте метод с OpenDSObject ADS_READONLY_SERVER)
'value to grab the "closest" domain controller (Важное значение "ближайший" контроллер домена)

'Connect to user object in the domain (Подключение к объекту пользователя в домене)
Set objUser = objNameSpace.OpenDSObject( _
"WinNT://" & strDomain & "/" & strUserID, "", "", ADS_READONLY_SERVER)
'Process each group (В процессе каждой группы)
For Each objGroup In objUser.Groups
'Add group name to list (Добавить название группы к списку)
strUserGroups = strUserGroups & objGroup.Name & ","
Next
Set objNameSpace = Nothing

End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Function: InGroup
' Purpose: Determine if user belongs to specified group
' Input: Name of group to test for membership
' Output: True or False
' Usage: If InGroup("Domain Admins") Then <do something>
' Requirements:
' strUserGroups must have been previously populated via
' GetLocalGroupMembership and/or GetGlobalGroupMembership
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Function InGroup(strGroup)

On Error Resume Next

InGroup = False
'Search strUserGroups for strGroup
If Instr( 1, LCase( strUserGroups ), LCase( strGroup ), 1) Then InGroup = True

End Function

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Sub: GetSystemInfo
' Purpose: Gather basic info about local system
' Input:
' Output: strDomain, strOSProdType, strWorkstation, strLogonPath
' Usage: Call GetSystemInfo
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Sub GetSystemInfo

On Error Resume Next

'Get domain name (Получить имя домена)
If objWshShell.ExpandEnvironmentStrings( "%OS%" ) = "Windows_NT" Then
strDomain = objWshNetwork.UserDomain
Else
strDomain = objWshShell.RegRead( "HKLMSystemCurrentControlSet" & _
"ServicesMSNP32NetWorkProviderAuthenticatingAgent" )
End If

'Get Product Type from registry (WinNT, LanmanNT, ServerNT) (Получить Тип продукта из реестра (WinNT, LanmanNT, ServerNT)
strOSProdType = objWshShell.RegRead( _
"HKLMSystemCurrentControlSetControlProductOptionsProductType")

'Get computer name (Получить имя компьютера)
If IsTerminalServerSession = True Then
'Set strWorkstation to the real name and not the name of the server
strWorkstation = objWshShell.ExpandEnvironmentStrings( "%CLIENTNAME%" )
Else
strWorkstation = objWshNetwork.ComputerName
End If

'Get the path to the location from where the script is running (Получить путь к месту, откуда скрипт работает)
strLogonPath = Left( Wscript.ScriptFullName, _
( InstrRev( Wscript.ScriptFullName, "") -1))

End Sub

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Function: IsTerminalServer
' Purpose: Determine if the script is running in a terminal server session
' Input:
' Output:
' True if running in a terminal server session
' False if not running in a terminal server session
' Usage:
' If IsTerminalServerSession = True Then <Do Something>
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Private Function IsTerminalServerSession

On Error Resume Next

Dim strName

'Detect if this is a terminal server session (Обнаружить, если это сессия терминального сервера)
'If it is, set some names to the terminal server client name (Если она есть, установить некоторые имена, чтобы имя клиента сервера терминалов)
strName = objWshShell.ExpandEnvironmentStrings( "%CLIENTNAME%" )
If strName <> "%CLIENTNAME%" AND strName <> "" Then _
IsTerminalServerSession = True

End Function

'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Sub: Cleanup
' Purpose: Release common objects and exit script
' Input:
' Output:
' Usage: Call Cleanup
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Sub Cleanup

On Error Resume Next

Set objFileSys = Nothing
Set objWshNetwork = Nothing
Set objWshShell = Nothing
Set objIntExplorer = Nothing

'Exit script
Wscript.Quit()

End Sub

На том же сайте пользователем Lamer-1 был выложен более простой скрипт.
Цитата
Set objWshNetwork = CreateObject( "WScript.Network" ) 'Создание объекта WshNetwork

Function MapDrv(DrvLet, UNCPath) 'функция подключения сетевого диска

Dim objFSO
Dim Drive

Set objFSO = CreateObject("Scripting.FileSystemObject") 'Создание объекта FileSystemObject

If objFSO.DriveExists(DrvLet) Then
objWshNetwork.RemoveNetworkDrive DrvLet,true, true 'происходит дисконнект диска Z
End If

WScript.Sleep 100 'пауза

objWshNetwork.MapNetworkDrive DrvLet, UNCPath 'Подсключение указанного диска с именем DrvLet и с сетевым путем UNCPath

End Function

MapDrv "Z:", "\Имя сервераимя шары" 'Вызов функции маппирования с заданными параметрами

Я его привел к следующему виду:
Цитата
Dim objWshNetwork

Const FileSrv1 = "\Server00"

Set objWshNetwork = CreateObject( "WScript.Network" ) 'Создание объекта WshNetwork

WScript.Sleep 100 'пауза

MapDrv "Z:", FileSrv1 & "downloads$","Задания" 'Вызов функции маппирования с заданными параметрами
MapDrv "M:", FileSrv1 & "MAIL$","Mail" 'Вызов функции маппирования с заданными параметрами
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Function MapDrv(DrvLet, UNCPath, DrvName) 'функция подключения сетевого диска

Dim objFSO, oShell

Set objFSO = CreateObject("Scripting.FileSystemObject") 'Создание объекта FileSystemObject
Set objoShell = CreateObject("Shell.Application")

On Error Resume Next

If objFSO.DriveExists(DrvLet) Then
objWshNetwork.RemoveNetworkDrive DrvLet, true, true 'происходит дисконнект дисков
End If

objWshNetwork.MapNetworkDrive DrvLet, UNCPath 'Подсключение указанного диска с именем DrvLet и с сетевым путем UNCPath
objoShell.NameSpace(DrvLet).Self.Name = DrvName
End Function
Диски подгружаются на ура но не всем пользователям нужен диск mail.

Разбираясь с первым листингом пытался через WScript.Echo strUserID получить значение но скрипт что-то питюкает и без ошибок вываливаеться в командную строку.
Закомментировав строку
Цитата
Const UseNTServer = 0
'to Windows Servers.
'Values are: 1 (Yes) OR 0 (No)
WScript.Echo strUserID начинает возвращать имя пользователя но вот проделов все тоже с strDomain, strUserGroups все четно выскакивает в командную строку. Как правильно запустить пошаговую отладку?

Автор: Egor Четверг, 08 Апреля 2010, 22:47

Цитата(Theridiidae @ Сегодня, 16:35)
Не знаю точно какие параметры команды NET у Win7x86 но Win7x64 команду net use z: \server00downloads$ не проглатывает, ругается.

Немного не в тему... Работает. Вы уверены, что правильно команду показали? Вот так будет работать:
net use z: \\server00\downloads$

Автор: Theridiidae Пятница, 09 Апреля 2010, 7:57

Egor большое спасибо за желание помочь. Это я оформляя пост два раза дал маху

Цитата
Дал маху не я  smile.gif  Оказываеться при редактировании поста форум затирает 2ва обратных слэша  biggrin.gif
конечно же "net use z: \\server00\downloads$". Иначе как бы оно работало на машинах с WinXP. Я пробовал непосредственно на самой машине Win7x64 запустить "net use z: \\server00\downloads$" в ответ получил, дословно не помню, что-то вроде не правильно указаны параметры или просто вываливался в синтаксис команды.

Автор: kenm Пятница, 09 Апреля 2010, 20:34

Theridiidae
Есть такой прекрасный командный интерпретатор kixtart предназначенный специально для написания logon-scripts, код для подключения сетевого диска в зависимости от членства в группе выглядит так

Код

use Z /DELETE
if InGroup("AllManagers") > 0
use Z: "\\server.domain.ru\FS$"
endif

http://www.kixtart.org/
а на vbs как говорится "много букв"

Автор: Egor Понедельник, 12 Апреля 2010, 13:41

Цитата(Theridiidae @ Пятница, 09 Апреля 2010, 7:57)
Win7x64 запустить "net use z: \\server00\downloads$" в ответ получил, дословно не помню, что-то вроде не правильно указаны параметры или просто вываливался в синтаксис команды.

Вот это и удивительно. Смотрите: домен на 2008 в натив моде, клиенты XP, VISTA, Win7 (х32/х64). Работает GPO с простейшим скриптом
@echo off
net use * /delete /y
net use o: \\domain.ru\doc

Все работает, все подключается для всех систем.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)