Лучший отвечающий
Как передать и обработать массив строк с пробелами в скрипт Powershell?

Вопрос
-
Добрый день!
Помогите пожалуйста разобраться в следующем...Есть рабочий скрипт который принимает 6 параметров
Param ( [Parameter(Mandatory=$true, Position=0)] [ValidateNotNullOrEmpty()] [string] $EndPoint , [Parameter(Mandatory=$true, Position=1)] [int] $Port , [Parameter(Mandatory=$true, Position=2)] [string] $IMessage , [Parameter(Mandatory=$true, Position=3)] [string] $idn , [Parameter(Mandatory=$true, Position=4)] [string] $phone , [Parameter(Mandatory=$true, Position=5)] [string] $Message )
и выполняет отправку СМС, которые нужно переделать под отправку нескольких СМС за раз. т.е. чтобы передавались параметры не так
./sms.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage "secret" -idn "1111-1111-1111-1113" -phone "XXXXXXXXXX" -Message "Текст сообщения"
а так
./sms.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage "secret" -Message {"1111-1111-1111-1113" "XXXXXXXXXX" "Текст сообщения"}, {"1111-1111-1111-1114" "XXXXXXXXXX" "Текст сообщения 2"},{"1111-1111-1111-1115" "XXXXXXXXXX" "Текст сообщения 3"},{"1111-1111-1111-1116" "XXXXXXXXXX" "Текст сообщения 4"}
Вот только как это сделать, если в Тексте сообщения присутствуют пробелы?
Нашел в интернете такое
[Parameter(ValueFromRemainingArguments=$true)][String[]]$Message
только не разберусь как это разобрать потом чтобы ТекстСообщения выделился в отдельную переменную.
Заранее спасибо.
18 июля 2019 г. 12:39
Ответы
-
Из 1С запросом получаю СМС для отправки, через COMОбъект("WScript.Shell")
Процесс = ОбъектОболочка.Exec(СтрокаКоманды);
ТекстРезультата = ПрочитатьПотокВыводаПроцесса(Процесс, "StdOut", 100);запускается выполнение скрипта, в который нужно передать все СМС сразу. Затем читаю результат выполнения скрипта. Сейчас осуществляется отправка в цикле по одной (пока получается только так). Потому нужно переделать скрипт чтобы он принимал все СМС для отправки.
Скрипт же отправляет на СМС-шлюз сообщение в виде "<uid/>UID</uid><phone/>PhoneNumber</phone><text/>TEXT</text> и получает подтверждение после каждой отправки.
Вот и думаю, или формировать json в строку и передавать эту строку в скрипт (пока не знаю как) или массив строк содержащих UID, Phone и Text.
Так как вы предложили получилось хорошо
-Messages "First message", "Second Message", "Hello worLD"
Вот только как теперь сделать чтобы это было так?
-Messages {"UID1", "Phone1", "Hello worLD"}, {UID2", "Phone2", "Hello worLD"}, {UID3", "Phone3", "Hello worLD"}, и т.д.
в поше как и в других языках есть свой синтаксис
в частности конструкции означают следующее:
{...} - скрипт блок
@(...) - массив
@{...} - хеш таблица
цикл вам скорее всего делать придется, хоть уже в поше а не 1с, но не суть
param ( [string[]]$UIDs, [string[]]$Phones, [string[]]$messages ) If ((($UIDs | measure-object).count -ne ($Phones | measure-object).count) -or (($UIDs | measure-object).count -ne ($Messages | measure-object).count))){ write-host "parameter set incorrect" } else { $elementqtt = ($UIDs | measure-object).count } foreach ($i in 0..$($elementqtt-1)){ write-host "[$i UID] $($UIDs[$i])" write-host "[$i Phone] $($Phones[$i])" write-host "[$i MSG] $($Messages[$i])" }
.\script.ps1 -UIDs "UID1", "UID2", "UID3" -Phones "Phone1", "123", "phon e3" -Messages "first message", "2nd msg", "third me ssage"
вариант решения через хеш таблицу будет выглядеть так:
param ( $SMSParameters ) $i = 1 foreach ($SMSParameter in $SMSParameters){ Write-Host "[$i UID] $($SMSParameter.UID)" Write-Host "[$i Phone] $($SMSParameter.Phone)" Write-Host "[$i MSG] $($SMSParameter.Message)" $i++ }
.\script.ps1 -SMSParameters @(@{uid = "uid1"; phone = "phone1"; message = "msg 1"}, @{uid = "uid2"; phone = "phone2"; message = "msg 2"})
The opinion expressed by me is not an official position of Microsoft
- Изменено Vector BCOModerator 18 июля 2019 г. 16:52
- Помечено в качестве ответа Vladislav.S 19 июля 2019 г. 4:24
- Снята пометка об ответе Vladislav.S 19 июля 2019 г. 7:57
- Помечено в качестве ответа Vladislav.S 19 июля 2019 г. 8:30
- Снята пометка об ответе Vladislav.S 19 июля 2019 г. 8:30
- Помечено в качестве ответа Vladislav.S 19 июля 2019 г. 8:40
18 июля 2019 г. 14:37Модератор -
Из консоли PS работает так
PS C:\Users\User> C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -command {C:\Users\User\Documents\sms_v13.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage secret -SMSParameters @(@{idn = '1111'; phone = '89999999999'; message = 'Текст сообщения'})}
а вот из cmd просто выводит содержимое в -command {...}
выводит такое
C:\Users\User\Documents\sms_v13.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage secret -SMSParameters @(@{idn = '1111'; phone = '89999999999'; message = 'Текст сообщения'})
А это уже специфика CMD
Саму команду запихиваете в двойные кавычки вместо фигурных скобок и все работает
Только обратите внимание что внутри самой команды используются одинарнуе кавычки
The opinion expressed by me is not an official position of Microsoft
- Помечено в качестве ответа Vladislav.S 19 июля 2019 г. 8:49
19 июля 2019 г. 8:35Модератор
Все ответы
-
param ( [String[]]$Messages ) $i=1 foerach ($Message in $Messages){ Write-host "[$i] $Message"
$i++ }
.\script.ps1 -Messages @('First message', ''Second Message', 'Hello worLD')
UPD По непонятным для меня причинам выв условии задачи говорите про несколько смс, и можно подумать что речь идет именно про сообщения ($Message) но в пример вы написали попытку передать весь набор из 6 параметров в переменную $Message
Проясните условия задачи и уточните откуда беруться упомянутые параметры (вы их каждый раз набираете руками из головы или логика более простая и автоматизируеммая)?
The opinion expressed by me is not an official position of Microsoft
- Предложено в качестве ответа Alexander RusinovModerator 18 июля 2019 г. 13:06
- Изменено Vector BCOModerator 18 июля 2019 г. 14:50
18 июля 2019 г. 13:01Модератор -
Из 1С запросом получаю СМС для отправки, через COMОбъект("WScript.Shell")
Процесс = ОбъектОболочка.Exec(СтрокаКоманды);
ТекстРезультата = ПрочитатьПотокВыводаПроцесса(Процесс, "StdOut", 100);запускается выполнение скрипта, в который нужно передать все СМС сразу. Затем читаю результат выполнения скрипта. Сейчас осуществляется отправка в цикле по одной (пока получается только так). Потому нужно переделать скрипт чтобы он принимал все СМС для отправки.
Скрипт же отправляет на СМС-шлюз сообщение в виде "<uid/>UID</uid><phone/>PhoneNumber</phone><text/>TEXT</text> и получает подтверждение после каждой отправки.
Вот и думаю, или формировать json в строку и передавать эту строку в скрипт (пока не знаю как) или массив строк содержащих UID, Phone и Text.
Так как вы предложили получилось хорошо
-Messages "First message", "Second Message", "Hello worLD"
Вот только как теперь сделать чтобы это было так?
-Messages {"UID1", "Phone1", "Hello worLD"}, {UID2", "Phone2", "Hello worLD"}, {UID3", "Phone3", "Hello worLD"}, и т.д.
- Изменено Vladislav.S 18 июля 2019 г. 13:52 редактирование
18 июля 2019 г. 13:42 -
Из 1С запросом получаю СМС для отправки, через COMОбъект("WScript.Shell")
Процесс = ОбъектОболочка.Exec(СтрокаКоманды);
ТекстРезультата = ПрочитатьПотокВыводаПроцесса(Процесс, "StdOut", 100);запускается выполнение скрипта, в который нужно передать все СМС сразу. Затем читаю результат выполнения скрипта. Сейчас осуществляется отправка в цикле по одной (пока получается только так). Потому нужно переделать скрипт чтобы он принимал все СМС для отправки.
Скрипт же отправляет на СМС-шлюз сообщение в виде "<uid/>UID</uid><phone/>PhoneNumber</phone><text/>TEXT</text> и получает подтверждение после каждой отправки.
Вот и думаю, или формировать json в строку и передавать эту строку в скрипт (пока не знаю как) или массив строк содержащих UID, Phone и Text.
Так как вы предложили получилось хорошо
-Messages "First message", "Second Message", "Hello worLD"
Вот только как теперь сделать чтобы это было так?
-Messages {"UID1", "Phone1", "Hello worLD"}, {UID2", "Phone2", "Hello worLD"}, {UID3", "Phone3", "Hello worLD"}, и т.д.
в поше как и в других языках есть свой синтаксис
в частности конструкции означают следующее:
{...} - скрипт блок
@(...) - массив
@{...} - хеш таблица
цикл вам скорее всего делать придется, хоть уже в поше а не 1с, но не суть
param ( [string[]]$UIDs, [string[]]$Phones, [string[]]$messages ) If ((($UIDs | measure-object).count -ne ($Phones | measure-object).count) -or (($UIDs | measure-object).count -ne ($Messages | measure-object).count))){ write-host "parameter set incorrect" } else { $elementqtt = ($UIDs | measure-object).count } foreach ($i in 0..$($elementqtt-1)){ write-host "[$i UID] $($UIDs[$i])" write-host "[$i Phone] $($Phones[$i])" write-host "[$i MSG] $($Messages[$i])" }
.\script.ps1 -UIDs "UID1", "UID2", "UID3" -Phones "Phone1", "123", "phon e3" -Messages "first message", "2nd msg", "third me ssage"
вариант решения через хеш таблицу будет выглядеть так:
param ( $SMSParameters ) $i = 1 foreach ($SMSParameter in $SMSParameters){ Write-Host "[$i UID] $($SMSParameter.UID)" Write-Host "[$i Phone] $($SMSParameter.Phone)" Write-Host "[$i MSG] $($SMSParameter.Message)" $i++ }
.\script.ps1 -SMSParameters @(@{uid = "uid1"; phone = "phone1"; message = "msg 1"}, @{uid = "uid2"; phone = "phone2"; message = "msg 2"})
The opinion expressed by me is not an official position of Microsoft
- Изменено Vector BCOModerator 18 июля 2019 г. 16:52
- Помечено в качестве ответа Vladislav.S 19 июля 2019 г. 4:24
- Снята пометка об ответе Vladislav.S 19 июля 2019 г. 7:57
- Помечено в качестве ответа Vladislav.S 19 июля 2019 г. 8:30
- Снята пометка об ответе Vladislav.S 19 июля 2019 г. 8:30
- Помечено в качестве ответа Vladislav.S 19 июля 2019 г. 8:40
18 июля 2019 г. 14:37Модератор -
Круто! Спасибо!
Завтра опробую.
Цикл изначально планировалось выполнять в PS, т.к. это должно быть быстрее. Не придется для каждого СМС создавать COMОбъект, а все будет выполнятся в одном.
Получится вызвать из .Exec передав ему ..\powershell.exe ..\sms.ps1 ... (вариант решения через хеш таблицу)? Или есть подводные камни? И какой из предложенных вами способов предпочтительнее по скорости и надежности?
- Изменено Vladislav.S 18 июля 2019 г. 17:23 редактирование
18 июля 2019 г. 17:07 -
думаю что будут подобны по скорости учитывая что количество итераций будет аналогично.
насчет вариатнов вызова скрипта из головы ничего не скажу, нужен комп и тесты
The opinion expressed by me is not an official position of Microsoft
- Изменено Vector BCOModerator 19 июля 2019 г. 6:17
18 июля 2019 г. 17:14Модератор -
При таком вызове
C:\Users\User>C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -file C:\Users\User\Documents\sms_v13.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage secret -SMSParameters @{@{uid = "1111"; phone = "89999999999"; message = "Текст сообщения"}} C:\Users\user\Documents\sms_v13.ps1 : Не удается найти позиционный параметр, принимающий аргумент "=". + CategoryInfo : InvalidArgument: (:) [sms_v13.ps1], ParentContainsErrorRecordException + FullyQualifiedErrorId : PositionalParameterNotFound,sms_v13.ps1
Причем при обычном вызове
C:\Users\User\Documents\sms_v13.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage "secret" -SMSParameters @(@{uid = "1111-1111-1111"; phone = "89999999999"; message = "Сообщение 1"})
Все нормально
В чем причина и как ее исправить?
- Изменено Vladislav.S 19 июля 2019 г. 7:12 редактирование
19 июля 2019 г. 6:49 -
если вызывать так
-SMSParameters "@(@{uid = '1111-1111-1111'; phone = '89999999999'; message = 'Сообщение 1'})"
то скрипт вываливается по ошибке (прописано в скрипте) от СМС-шлюза. Возможно строка отправки при таком вызове не корректно формируется.
- Изменено Vladislav.S 19 июля 2019 г. 7:14 реадктирование
19 июля 2019 г. 7:01 -
Осталось попробовать НЕ через хеш таблицу, там нет символа "="19 июля 2019 г. 7:04
-
Осталось попробовать НЕ через хеш таблицу, там нет символа "="
Копируете неправильно
Вот пример вызова с искользования PowerShell.exe
The opinion expressed by me is not an official position of Microsoft
- Изменено Vector BCOModerator 19 июля 2019 г. 7:36
19 июля 2019 г. 7:16Модератор -
При таком вызове
C:\Users\User>C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -file C:\Users\User\Documents\sms_v13.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage secret -SMSParameters @{@{uid = "1111"; phone = "89999999999"; message = "Текст сообщения"}} C:\Users\user\Documents\sms_v13.ps1 : Не удается найти позиционный параметр, принимающий аргумент "=". + CategoryInfo : InvalidArgument: (:) [sms_v13.ps1], ParentContainsErrorRecordException + FullyQualifiedErrorId : PositionalParameterNotFound,sms_v13.ps1
Причем при обычном вызове
C:\Users\User\Documents\sms_v13.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage "secret" -SMSParameters @(@{uid = "1111-1111-1111"; phone = "89999999999"; message = "Сообщение 1"})
Все нормально
В чем причина и как ее исправить?
В примере где вываливается ошибка вы используете неправильные скобки в отличии от второго примера где скобки вы используете правильные
если вызывать так
-SMSParameters "@(@{uid = '1111-1111-1111'; phone = '89999999999'; message = 'Сообщение 1'})"
то скрипт вываливается по ошибке (прописано в скрипте) от СМС-шлюза. Возможно строка отправки при таком вызове не корректно формируется.
Что же до этого вызова то вы передаете вместо массива хеш таблиц 1 строку которая соответвенно и не расскладывается на компоненты
The opinion expressed by me is not an official position of Microsoft
19 июля 2019 г. 7:32Модератор -
При таком вызове возникает ошибка
C:\Users\User>C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -file C:\Users\User\Documents\sms_v14.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage "secret" uids "1111", "2222", "3333" -Phones "89999999999", "89999999999", "89999999999" -Messages "first message", "2nd msg", "third message" C:\Users\User\Documents\sms_v14.ps1 : Не удается найти позиционный параметр, принимающий аргумент "2222,". + CategoryInfo : InvalidArgument: (:) [sms_v14.ps1], ParentContainsErrorRecordException + FullyQualifiedErrorId : PositionalParameterNotFound,sms_v14.ps1
Причем при вызове таком все нормально
C:\Users\User\Documents\sms_v14.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage "secret" -uids "1111", "2222", "3333" -Phones "89999999999", "89999999999", "89999999999" -Messages "first message", "2nd msg", "third message"
- Изменено Vladislav.S 19 июля 2019 г. 7:45 редактирование
19 июля 2019 г. 7:44 -
Если удалить пробелы, то скрипт вылетает по ошибке
"1111,2222,3333#error. Extra numbers entered"
это когда длинна номера больше 11 символов, а если параметры заключить в @{}, то
"@{1111,2222,3333}#error. Number should start from 8"
, это значит номер начинает не с "8".
19 июля 2019 г. 7:56 -
Из консоли PS работает так
PS C:\Users\User> C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -command {C:\Users\User\Documents\sms_v13.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage secret -SMSParameters @(@{idn = '1111'; phone = '89999999999'; message = 'Текст сообщения'})}
а вот из cmd просто выводит содержимое в -command {...}
выводит такое
C:\Users\User\Documents\sms_v13.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage secret -SMSParameters @(@{idn = '1111'; phone = '89999999999'; message = 'Текст сообщения'})
- Изменено Vladislav.S 19 июля 2019 г. 8:19 редактирование
19 июля 2019 г. 8:16 -
У меня вызов из 1С получается как из cmd. Передавал результат выполнения скрипта в 1С, там строка как в сообщении выше, только вместо русского текста абракадабра19 июля 2019 г. 8:34
-
Из консоли PS работает так
PS C:\Users\User> C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe -command {C:\Users\User\Documents\sms_v13.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage secret -SMSParameters @(@{idn = '1111'; phone = '89999999999'; message = 'Текст сообщения'})}
а вот из cmd просто выводит содержимое в -command {...}
выводит такое
C:\Users\User\Documents\sms_v13.ps1 -Endpoint 192.168.0.1 -Port 10000 -IMessage secret -SMSParameters @(@{idn = '1111'; phone = '89999999999'; message = 'Текст сообщения'})
А это уже специфика CMD
Саму команду запихиваете в двойные кавычки вместо фигурных скобок и все работает
Только обратите внимание что внутри самой команды используются одинарнуе кавычки
The opinion expressed by me is not an official position of Microsoft
- Помечено в качестве ответа Vladislav.S 19 июля 2019 г. 8:49
19 июля 2019 г. 8:35Модератор -
АААААААААААА ЗАРАБОТАЛО!!!!
Огромное вам спасибо!!!!
19 июля 2019 г. 8:40 -
Теперь возникла еще одна проблема. До этого я это все делал на локальной базе и при выполнении скрипта открывалось окно PS, выполнялся скрипт, отправлялись СМС, 1С считавала результат через Exec.StdOut, окно закрывалось и все ок. При выполнении на сервере от пользователя 1Сv83 запускается скрипт, окно НЕ ПОЯВЛЯЕТСЯ (но процесс powershell запущен), отправляется СМС, и код 1С стопарится на Exec.StdOut.AtEndOfStream. В 1С такая конструкция
ОбъектОболочка = Новый COMОбъект("WScript.Shell"); Процесс = ОбъектОболочка.Exec(СтрокаКоманды); Поток = Процесс.StdOut; Пока НЕ Поток.AtEndOfStream Цикл .........
Вот на "Пока НЕ Поток.AtEndOfStream Цикл" код стопарится при выполнении скрипта на сервере.
В чем может быть проблема?
19 июля 2019 г. 12:24 -
скрипт стопориться может на executionpolicy или на каких то 1с механизмах о которых у меня нет ни малейшего понятия
The opinion expressed by me is not an official position of Microsoft
19 июля 2019 г. 12:39Модератор -
весь вывод происходил в консоли через Write-Host из которой потом все считывалось. Как заставить запускаться окно ps?19 июля 2019 г. 12:41
-
весь вывод происходил в консоли через Write-Host из которой потом все считывалось. Как заставить запускаться окно ps?
вы имеете в виду read-host?
окно поша появляется у того от имени кого запускается консоль, в вашем случае это сервисный пользюк 1с.
интерактивные скрипты это не лучший вариант для автоматизации
если вам нужно что-то для отладки создавайте и пишите логи, но трекинг вывода и тем более ввод параметров через консоль это не оптимальные решения
лог можете писать через start-transcript (в начале скрипта) и stop-transcript (в конце скрипта)
если есть проблемы со скриптом приведите скрипт
The opinion expressed by me is not an official position of Microsoft
- Помечено в качестве ответа Vector BCOModerator 19 июля 2019 г. 13:14
- Снята пометка об ответе Vector BCOModerator 19 июля 2019 г. 13:14
- Помечено в качестве ответа Vector BCOModerator 19 июля 2019 г. 13:14
- Снята пометка об ответе Vector BCOModerator 19 июля 2019 г. 13:14
- Изменено Vector BCOModerator 19 июля 2019 г. 13:16
19 июля 2019 г. 13:11Модератор -
Читаю из скрипта через exec.stdout.readline.
Видимо придется все переделывать (имею ввиду разбор вывода в 1С), ну так делать ничего. У пользюка 1Сного нет нет ни сеанса ни профиля, а так хорошо на локальной базе выходило...Вариантов кроме как писать результат в файл похоже нету? Или можно как-то придумать чтобы скрипт вернул значение в exec.stdout?
Скрипта сейчас нет под рукой, на работе. Да и просто там все, вот тут моя предыдущая тема только немного изменился с тех пор (разбил на два цикла; появилось немного ветвлений типо если сервис вернул error, то Write-Host error и break и т.д.; параметры передаю, а не заполняю интерактивно; успешный результат вывожу через Write-Host $UID+" "+$Status(ок или error) в цикле для каждого СМСа; ну и ваш код из этой темы естественно). Так-то все работает даже на сервере если со своего сеанса запускать.
Может есть все-таки возможность как-то заставить скрипт "сэмулировать" вывод, что бы можно было прочитать через exec.stdout.readline?. Типо в "выводной поток". Понимаю что размыто выражаюсь. В powershell так себе шарю, на уровне скопипастил 2-3 скрипта, подшаманил и запихал все в один. Или только в файл, а потом удалять его?
- Изменено Vladislav.S 20 июля 2019 г. 21:57 редактирование
20 июля 2019 г. 21:45 -
У меня есть догадка что вам требуется Write-Output вместо Write-Host
Попробуйте протестировать в своей среде и уточните получаете ли то что требуется. Write-Output штатно перенаправляется в stdOut, Write-Host - нет
The opinion expressed by me is not an official position of Microsoft
20 июля 2019 г. 22:08Модератор -
После отпуска вернулся к данной задаче и ... решилось.
Сначала по вашему совету изменил Write-Host на Write-Output - результата нету, все также (скрипт зависал). И потом нашел такую статью Вызов Powershell с методом WshShell.Exec () приводит к зависанию скрипта в коде 1С перед чтением потока добавил
Процесс.StdIn.Close();
Процесс - это WScript.Shell.Exec
И все получилось!
P.S. Write-Output использую в выводе.
Еще раз спасибо за помощь!
5 августа 2019 г. 10:01 -
Единственный вопрос пока такой - Это я сейчас тестю на тестовом сервере (Win Srv 2008 sp2), а если на боевом (Win Srv 2012) уже не будет проблем с потоком?5 августа 2019 г. 10:04
-
А и плюс к этому вызов скрипта делаю с такими параметрами
"C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe"
+" -noninteractive "
+" -noprofile "
+" -command "
+""""
Это из 1С, но думаю что понятно.
5 августа 2019 г. 10:07 -
Единственный вопрос пока такой - Это я сейчас тестю на тестовом сервере (Win Srv 2008 sp2), а если на боевом (Win Srv 2012) уже не будет проблем с потоком?
думаю что проблем на старших версиях ос быть не должноThe opinion expressed by me is not an official position of Microsoft
5 августа 2019 г. 10:08Модератор