Войти

Показать полную графическую версию : Поиск разноименных ярлыков по свойству(ам)


Шальной.
20-01-2014, 16:05
Здравствуйте, коллеги.

Не сталкивался ли кто-нибудь с описанной в заголовке задачей?

Поясню: пользователи создавали себе ярлыки на сетевые папки, расположенные на разных серверах. Имена ярлыков произвольные. Хотелось бы объединить все сетевые папки на одном файл-сервере. Перенести данные и ACL, конечно, не проблема, но что делать с ярлыками, которые пользователи себе насоздавали (тысячи их)?

Вручную менять ярлыки очень долго и муторно. Хотелось бы написать некий скрипт, который бы анализировал поле "Объект" всех ярлыков на рабочем столе и при нахождении соответствия удалял ярлык, а вместо него копировал бы другой с определенным стандартизированным именем.

На примере это выглядит следующим образом: есть два пользователя - Вася и Коля, которые используют сетевую папку \\SRV1\Folder\. Вася создал ярлык к папке \\SRV1\Folder\ и назвал его "Общая", Коля же, создав ярлык туда же назвал его "Сервер". Неожиданно имя сервера изменилось на SRV2 и ярлыки перестали работать. Было принято решение для всех Вась и Коль создать групповую политику, которая находила бы их ярлыки к папке \\SRV1\Folder\, и либо меняла путь на \\SRV2\Folder\, либо удаляла старые ярлыки, указывающие на \\SRV1\Folder\, а вместо них копировала на рабочий стол новые, указывающие на \\SRV2\Folder\.

С уважением,

Iska
20-01-2014, 18:09
а вместо него копировал бы другой с определенным стандартизированным именем. »
Копировать — не стоит. Категорически. Либо создавать заново, либо менять назначение у существующего. Например (не проверялось):
Option Explicit

Dim objDictionary

Dim objFSO
Dim objFile
Dim objWshShell

Dim elem


Set objDictionary = WScript.CreateObject("Scripting.Dictionary")

objDictionary.Add "\\SRV1\Folder", "\\SRV2\Folder"
objDictionary.Add "\\SRV1\Folder2", "\\SRV3\Folder3"

Set objWshShell = WScript.CreateObject("WScript.Shell")
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

For Each objFile In objFSO.GetFolder(objWshShell.SpecialFolders("Desktop")).Files
If LCase(objFSO.GetExtensionName(objFile.Name)) = "lnk" Then
With objWshShell.CreateShortcut(objFile.Path)
For Each elem In objDictionary.Keys
If LCase(elem) = LCase(.TargetPath) Then
.TargetPath = objDictionary.Item(elem)

.Save
End If
Next
End With
End If
Next

objDictionary.RemoveAll

Set objDictionary = Nothing
Set objFSO = Nothing
Set objWshShell = Nothing

WScript.Quit 0

Foreigner
20-01-2014, 18:40
Шальной., Попробуйте, для домашнего ноутбука с локальными путями работает

pushd "$home\desktop"
$shell = new-object -comobject wscript.shell
gci *.lnk | % {

if ( $shell.createshortcut( $_ ).targetpath -eq '\\SRV1\Folder' ) {

$lnk = $shell.createshortcut( $_ )
$lnk.targetpath = '\\SRV2\Folder'
$lnk.save()

}

}

popd
[void][Runtime.InteropServices.Marshal]::ReleaseComObject( $shell )

Шальной.
20-01-2014, 19:08
Спасибо вам огромное, Iska и Foreigner!

И на VBS и на PowerShell сработало так, как и было необходимо!

Вы серьезно облегчили мне жизнь! :)

Не хочу показаться наглым, но т.к. я пока только вхожу в изучение скриптовых языков, не могли бы вы заодно показать, как заодно переименовать эти ярлыки, например в "Общий сетевой ресурс"?

Кстати, вопрос к Iska - почему копирование готового ярлыка это плохая идея? И если Вас не затруднит, не могли бы Вы прокомментировать строку objDictionary.Add "\\SRV1\Folder2", "\\SRV3\Folder3" »

С большущей благодарностью всем, :)

Foreigner
20-01-2014, 21:32
как заодно переименовать эти ярлыки, например в "Общий сетевой ресурс"? »

...
if ( $shell.createshortcut( $_ ).targetpath -eq '\\SRV1\Folder' ) {

$lnk = $shell.createshortcut( $_ )
$lnk.targetpath = '\\SRV2\Folder'
$lnk.save()
mv -literal $_ 'Общий сетевой ресурс.lnk'

}
...

Iska
20-01-2014, 22:23
показать, как заодно переименовать эти ярлыки, например в "Общий сетевой ресурс"? »
Например, так:
Option Explicit

Dim arrShares

Dim objFSO
Dim objFile
Dim objWshShell
Dim objWshShortcut

Dim elem


arrShares = Array( _
Array("\\SRV1\Folder", "\\SRV2\Folder", "Общий сетевой ресурс.lnk" ), _
Array("\\SRV1\Folder2", "\\SRV3\Folder3", "Общий сетевой ресурс 2.lnk") _
)

Set objWshShell = WScript.CreateObject("WScript.Shell")
Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

For Each objFile In objFSO.GetFolder(objWshShell.SpecialFolders("Desktop")).Files
If LCase(objFSO.GetExtensionName(objFile.Name)) = "lnk" Then
Set objWshShortcut = objWshShell.CreateShortcut(objFile.Path)

For Each elem In arrShares
If LCase(elem(0)) = LCase(objWshShortcut.TargetPath) Then
objWshShortcut.TargetPath = elem(1)
objWshShortcut.Save

Set objWshShortcut = Nothing

objFile.Name = elem(2)

Exit For
End If
Next
End If
Next

Set objFSO = Nothing
Set objWshShell = Nothing

WScript.Quit 0

почему копирование готового ярлыка это плохая идея? »
Потому что зачастую (а при «ручном» создании наверняка) в ярлык «имплантируется» идентификатор ссылки для сопоставления. В ряде сценариев поведение ярлыка становится непредсказуемым. Когда-то Microsoft выставляла утилиту, позволяющую удалить его из ярлыка. Потому я предпочитаю создание ярлыка его клонированию. В первую очередь, это относится, конечно, к ссылкам на локальный ресурс, а не на сетевой.

И если Вас не затруднит, не могли бы Вы прокомментировать строку:
objDictionary.Add "\\SRV1\Folder2", "\\SRV3\Folder3"
»
Я «улучшил» со своей стороны Ваше техзадание для поддержки замены более чем одного сетевого ресурса.

Шальной.
21-01-2014, 12:49
Отлично!

Просто супер!

Еще раз большое спасибо! :)

Единственный вопрос - если ярлыков ссылающихся на одно и то же расположение больше одного, то при запуске вылетает ошибка, говорящая о том, что ярлык с таким именем уже существует. Возможно ли в таком случае добавлять цифирку в скобочках, как в проводнике - "Общий сетевой ресурс (2).lnk"?

И если это не вызовет Ваш гнев - возможно ли использование знаков подстановки с этих скриптах? Поясню, есть сетевой ресурс \\SRV1\Folder\, а в нем папки Dir1, Dir2 и Dir3. И пользователь сделал ярлык не на сетевой ресурс \\SRV1\Folder\, а на папку внутри этого ресурса \\SRV1\Folder\Dir1. В этом случае, скрипт этот ярлык проигнорирует. Возможно ли использовать знаки подстановки (например знак "*"), для того чтобы создать ярлык на ресурс \\SRV2\Folder\Dir1. Т.е. некая часть пути была бы статично прописана, а другая часть пути была бы динамической.

С большим уважением ко всем,




© OSzone.net 2001-2012