Вики IT-KB

Пошаговые руководства, шпаргалки, полезные ссылки...

Инструменты пользователя

Инструменты сайта


apple-mac-os:macos-sequoia:automated-os-deployment-to-apple-mac-and-iphone-or-ipad-mobile-devices

Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

Предыдущая версия справа и слеваПредыдущая версия
Следующая версия
Предыдущая версия
apple-mac-os:macos-sequoia:automated-os-deployment-to-apple-mac-and-iphone-or-ipad-mobile-devices [10.12.2024 04:45] – ↷ Операцией перемещения обновлены ссылки Алексей Максимовapple-mac-os:macos-sequoia:automated-os-deployment-to-apple-mac-and-iphone-or-ipad-mobile-devices [24.09.2025 19:18] (текущий) Виталий Якоб
Строка 12: Строка 12:
 <code AppleScript> <code AppleScript>
 -- В скрипте используется утилита jq, которая встроена в macOS начиная с Sequoia. -- В скрипте используется утилита jq, которая встроена в macOS начиная с Sequoia.
--- При использовании более ранних версий, jq нужно установить дополнительно.+-- При использовании более ранних вресий, jq нужно установить дополнительно.
 -- Перед использованием с AppStore установить Apple Configurator 2, и выполнить установку средств автоматизации из меню. -- Перед использованием с AppStore установить Apple Configurator 2, и выполнить установку средств автоматизации из меню.
  
Строка 18: Строка 18:
 global LogPath global LogPath
 set LogPath to "/tmp/DevsRestore/logs/" set LogPath to "/tmp/DevsRestore/logs/"
 +
 +-- Определение версии ОС для правильной работы с system_profiler, т.к. в macOS 15 и macOS 26 DataType USB отличается
 +-- В дальнейшем могут быть другие изменения, поэтому вынесено наверх
 +set OSVer to system version of (system info)
 +global usbDataType
 +
 +if OSVer is greater than or equal to 26 then
 +  set usbDataType to "SPUSBHostDataType"
 +else
 +  set usbDataType to "SPUSBDataType"
 +end if
  
  
Строка 24: Строка 35:
 -- Получаем список подключенных устройств с помощью system_profiler -- Получаем список подключенных устройств с помощью system_profiler
 set SPResult to my systemprofilerDevList() set SPResult to my systemprofilerDevList()
--- Объединяем списки для получения требуемой инф. в одной списке+-- Объединяем списки для получаения требуемой инф. в одном списке
 set MergedList to my MergeLists(cfgutilResult, SPResult) set MergedList to my MergeLists(cfgutilResult, SPResult)
 --return MergedList --return MergedList
Строка 146: Строка 157:
       -- Проверяем ещё раз       -- Проверяем ещё раз
       set CurrentDownloads to (do shell script PSShellCommand) as integer       set CurrentDownloads to (do shell script PSShellCommand) as integer
-      -- Если очередная проверка не обнаружила параллельный процесс, считаем что он завершён+      -- Если очередная проверка не не обнаружила параллельный процесс, считаем что он завершён
       if CurrentDownloads is 1 then       if CurrentDownloads is 1 then
         -- Процесс завершён, можно продолжать         -- Процесс завершён, можно продолжать
Строка 154: Строка 165:
           return true           return true
         else         else
-          my WriteLog("Возможно, параллельный процесс загрузки был завершён некорректно", LogFileName)+          my WriteLog("Возможно, параллельный процесс загрузки был завешён некорреткно", LogFileName)
           my WriteLog("Попробуйте в ручную загрузить файл по ссылке" & linefeed & thisURL, LogFileName)           my WriteLog("Попробуйте в ручную загрузить файл по ссылке" & linefeed & thisURL, LogFileName)
           my WriteLog("Остановка процесса.", LogFileName)           my WriteLog("Остановка процесса.", LogFileName)
Строка 163: Строка 174:
       -- При достижении счётчика, останавливаем процесс       -- При достижении счётчика, останавливаем процесс
       if Counter is 5 then       if Counter is 5 then
-        my WriteLog("За последний час процесс загрузки образа не был завершён или есть зависший процесс curl.", LogFileName)+        my WriteLog("За послений час процесс загрузки образа не был завершён или есть зависший процесс curl.", LogFileName)
         my WriteLog("Остановка процесса.", LogFileName)         my WriteLog("Остановка процесса.", LogFileName)
         return false         return false
Строка 173: Строка 184:
   else if CurrentDownloads is 1 then   else if CurrentDownloads is 1 then
     set curlShellCommand to "curl -L --retry 5 --retry-delay 10 --retry-all-errors -J -o" & space & quoted form of thisFile & space & thisURL     set curlShellCommand to "curl -L --retry 5 --retry-delay 10 --retry-all-errors -J -o" & space & quoted form of thisFile & space & thisURL
-    my WriteLog("Запускаем скачивание:" & linefeed & curlShellCommand, LogFileName)+    my WriteLog("Запускаем скачиваение:" & linefeed & curlShellCommand, LogFileName)
     try     try
       do shell script curlShellCommand       do shell script curlShellCommand
Строка 319: Строка 330:
 on cfgutilDevList() on cfgutilDevList()
      
-  -- Получаем инф. о подключенных устройствах в формате JSON+  -- Получаем инф. о подключенных устройсвах в формате JSON
   set BaseJSON to do shell script "/usr/local/bin/cfgutil --format JSON list | jq"   set BaseJSON to do shell script "/usr/local/bin/cfgutil --format JSON list | jq"
-  -- Парсим JSON, выбирая нужные данные и сохраняем контент как CVS, разделитель ";"+  -- Парсим JSON, выберая нужные данные и сохраняем контент как CVS, разделитель ";"
   set ParsedCSV to do shell script "echo" & space & quoted form of BaseJSON & space & "| jq -r '.Output | to_entries[] | [.value.locationID, .value.ECID, .value.deviceType] | join(\";\")'"   set ParsedCSV to do shell script "echo" & space & quoted form of BaseJSON & space & "| jq -r '.Output | to_entries[] | [.value.locationID, .value.ECID, .value.deviceType] | join(\";\")'"
   -- Разбиваем на строки   -- Разбиваем на строки
Строка 343: Строка 354:
     -- Вторая часть ECID     -- Вторая часть ECID
     set ECID to item 2 of CSVParts     set ECID to item 2 of CSVParts
-    -- Третья часть DeviceType+    -- Третяя часть DeviceType
     set DeviceType to item 3 of CSVParts     set DeviceType to item 3 of CSVParts
          
Строка 351: Строка 362:
     set LocationID to "0x" & (do shell script "printf '%X' " & LocationID)     set LocationID to "0x" & (do shell script "printf '%X' " & LocationID)
          
-    -- Выполняем проверку существования log-файла с именем ECID устройства,+    -- Выполняем проверку сущестования log-файла с именем ECID устройства,
     -- Если лог есть, то считаем, что запускать повторно процедуру восстановления не нужно. Не добавляем в список результатов.     -- Если лог есть, то считаем, что запускать повторно процедуру восстановления не нужно. Не добавляем в список результатов.
     try     try
Строка 372: Строка 383:
 --Поиск подключенных устройств с помощью system_profiler --Поиск подключенных устройств с помощью system_profiler
 on systemprofilerDevList() on systemprofilerDevList()
-  --Ищем среди подключенных USB устройств имена в которых содержится Mac, DFU или Recovery.  +  --Получаем информацию о подключенных USB устройсвах, ищем только те в имени которых Mac, DFU или Recovery. 
-  -- Отображаем найденные строки, а так же 5 и 8 строку для отображения Serial Number и  +  --Так как формат system_profiler изменился начиная с macOS 26, учитываем разницу. 
-  -- Location. Location необходим в качестве ключа для объединения со списком cfgutilDevList() +  --Location необходим в качестве ключа для объединения со списком cfgutilDevList() 
-  set SPUSBInfo to do shell script "system_profiler SPUSBDataType awk '{ +  set SPUSBInfo to do shell script "system_profiler -json" & space & usbDataType & space & "jq -r 
-          lines[NR] = $0 +    .. | objects 
-      }  +    | select(._name? and (._name | strings | test(\"Mac|DFU|Recovery\"))) 
-      /Mac|DFU|Recovery/ {  +    | [ 
-          mac_dfu_recovery_line = NR +        ._name, 
-           mac_dfu_recovery_found = 1 +        (.USBDeviceKeySerialNumber // .serial_num // \"\")
-      }  +        (.USBKeyLocationID // .location_id // \"\"
-      /Serial Number:/ &&  mac_dfu_recovery_found && (NR == mac_dfu_recovery_line + 5) {  +      
-          serial_number_line = NR  +    | .[] 
-      }  +  '"
-      /Location ID:&&  mac_dfu_recovery_found && (NR == mac_dfu_recovery_line + 8) { +
-          if ( mac_dfu_recovery_found && serial_number_line && NR == mac_dfu_recovery_line + 8) { +
-              sub(/^ +/\"\", lines[mac_dfu_recovery_line]) +
-              sub(/^ +/, \"\", lines[serial_number_line]) +
-              sub(/^ +/\"\", $0+
-               +
-              print lines[mac_dfu_recovery_line+
-              print lines[serial_number_line+
-              print $0 +
-       +
-               mac_dfu_recovery_found = 0 +
-              serial_number_line = 0 +
-          } +
-      }'"+
      
   -- Разделяем вывод на строки   -- Разделяем вывод на строки
Строка 413: Строка 410:
          
     -- Модифицируем полученные данные приводя в нужный вид     -- Модифицируем полученные данные приводя в нужный вид
-    --Последний символ строки ":", уберём это 
-    set Model to text 1 thru -2 of Model 
     -- Серийный номер подключенный Mac отображается сразу, у iOS строка содержит множество другой информации     -- Серийный номер подключенный Mac отображается сразу, у iOS строка содержит множество другой информации
     -- Mac загруженный в DFU режиме не отображает серийный номер.     -- Mac загруженный в DFU режиме не отображает серийный номер.
Строка 443: Строка 438:
       0x00100000 --> 0x100000       0x00100000 --> 0x100000
       0x08310000 --> 0x8310000       0x08310000 --> 0x8310000
-      Поэтому конвертируем 0x08310000 в 8310000 и добавляем 0x спереди, чтобы значение соответствовало формату cfgutil+      Поэтому конвертируем 0x08310000 в 8310000 и добавляем 0x спереди, чтобы значение соответвовало формату cfgutil
   *)   *)
     --Вырезаем значение из строки     --Вырезаем значение из строки
-    set LocationID to text 14 thru 23 of LocationID+    --До macOS 26, в Location ID содержал номер порта, "0x14400000 / 9". 
 +    set LocationID to word 1 of LocationID
     set LocationID to "0x" & (do shell script "printf '%X' " & LocationID)     set LocationID to "0x" & (do shell script "printf '%X' " & LocationID)
          
-    -- Добавляем инф о каждом устройстве в подсписке в список+    -- Добавялем инф о каждом устройстве в подсписке в список
     set end of ResultList to {Model, Serial, LocationID}     set end of ResultList to {Model, Serial, LocationID}
   end repeat   end repeat
Строка 462: Строка 458:
 --=================== --===================
  
--- Обработчик для объединения списков+-- Обработчик для объединения объединения списков
 --https://www.macscripter.net/t/merge-2-arrays-by-key/76457/10 --https://www.macscripter.net/t/merge-2-arrays-by-key/76457/10
 --=================== --===================
Строка 478: Строка 474:
       -- Извлекаем значения подсписков из второго списка "List2" в подсписок "subList2"       -- Извлекаем значения подсписков из второго списка "List2" в подсписок "subList2"
       set {Value11, Value12, ID11} to subList2       set {Value11, Value12, ID11} to subList2
-      --Если ключевые значения равны, создаём итоговый новый список+      --Если ключевые занечения равны, создаём итоговый новый список
       if ID01 is equal to ID11 then       if ID01 is equal to ID11 then
         set end of ResultList to {Value01, Value11, Value12, Value02, ID01}         set end of ResultList to {Value01, Value11, Value12, Value02, ID01}
Строка 630: Строка 626:
 ^ Версия ОС ^ ^ Версия ОС ^
 | Apple macOS Sequoia (15.0)  | | Apple macOS Sequoia (15.0)  |
 +| Apple macOS Tahoe (26.0)  |
  
 ---- ----
apple-mac-os/macos-sequoia/automated-os-deployment-to-apple-mac-and-iphone-or-ipad-mobile-devices.1733805948.txt.gz · Последнее изменение: Алексей Максимов