Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Поиск разноименных ярлыков по свойству(ам) (http://forum.oszone.net/showthread.php?t=276121)

Шальной. 20-01-2014 16:05 2292782

Поиск разноименных ярлыков по свойству(ам)
 
Здравствуйте, коллеги.

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

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

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

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

С уважением,

Iska 20-01-2014 18:09 2292877

Цитата:

Цитата Шальной.
а вместо него копировал бы другой с определенным стандартизированным именем. »

Копировать — не стоит. Категорически. Либо создавать заново, либо менять назначение у существующего. Например (не проверялось):
читать дальше »
Код:

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 2292903

Шальной., Попробуйте, для домашнего ноутбука с локальными путями работает
Код:

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 2292925

Спасибо вам огромное, Iska и Foreigner!

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

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

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

Кстати, вопрос к Iska - почему копирование готового ярлыка это плохая идея? И если Вас не затруднит, не могли бы Вы прокомментировать строку
Цитата:

Цитата Iska
objDictionary.Add "\\SRV1\Folder2", "\\SRV3\Folder3" »

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

Foreigner 20-01-2014 21:32 2293025

Цитата:

Цитата Шальной.
как заодно переименовать эти ярлыки, например в "Общий сетевой ресурс"? »

Код:

...
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 2293062

Цитата:

Цитата Шальной.
показать, как заодно переименовать эти ярлыки, например в "Общий сетевой ресурс"? »

Например, так:
читать дальше »
Код:

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 2293304

Отлично!

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

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

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

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

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


Время: 03:24.

Время: 03:24.
© OSzone.net 2001-