Ответы пользователя по тегу PowerShell
  • Как из скрипта ps1 запустить другой powershell скрипт ps1 и передать ему массив аргументом?

    @MaxKozlov Куратор тега PowerShell
    Вы слишком много хотите от Start-Process :)
    Это просто winapi, которое не знает о том, что в качестве аргумента может быть не строка.
    Поэтому всё упирается в интерпретатор параметров, который в вызываемом скрипте.

    Я в своём примере в том самом вопросе не зря в called добавил ещё и вывод $args
    Если в первом скрипте аргументы формировать как
    $argumentList = '-noprofile', '-noexit', '-File', 'd:\called.ps1', "-FilePath `"$filepath`""
    $argumentList += $patterns

    А второй сделать как
    param(
      [string]$FilePath #,
    #  [array]$Patterns
    )

    То во втором именно в $args попадёт содержимое массива
    Но по любому второй скрипт должен знать, что ему куда передают

    Поэтому я такую проблему решал бы вообще с другой стороны :)

    Достаточно добавить в запускающий скрипт #requires -RunAsAdministrator
    и тогда запускаемому можно передавать всё что угодно, ведь его не надо будет запускать через
    Start-Process, а можно будет просто вызывать из первого
    Ответ написан
    2 комментария
  • Как из скрипта ps1 запустить от имени администратора другой powershell скрипт ps1 и передать ему параметры если в путях есть пробелы?

    @MaxKozlov Куратор тега PowerShell
    Варианты бывают разные, По сути то же, что и в комментариях, но выглядит чуть более аккуратно :)
    Особенно хорош вариант с -EncodedCommand, потому что там можно хоть целый скрипт написать

    call.ps1
    $filepath = "D:\test folder\with test file\myfile.exe"
    $patterns = "11223344/55667788"
    
    $argumentList = '-noprofile', '-noexit', '-File', 'd:\called.ps1', "-FilePath `"$filepath`"", "-patterns `"$patterns`""
    
    Start-Process powershell -Verb RunAs -ArgumentList $argumentList
    
    # Специально многострочный пример
    $command = @"
    d:\called.ps1 -FilePath `"$filepath`" -patterns `"$patterns`"
    "@
    $encodedCommand = [convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($command))
    
    Start-Process powershell -Verb RunAs -ArgumentList '-noprofile -noexit -EncodedCommand', $encodedCommand


    called.ps1
    #requires -RunAsAdministrator
    
    param(
      $FilePath,
      $Patterns
    )
    Write-Host "FilePath: >$FilePath<"
    Write-Host "Patterns: >$Patterns<"
    
    foreach ($a in $args) {
       Write-Host "Argument: >$a<"
    }
    Write-Host "---"
    Ответ написан
  • Какой метод лучше для задания по расписанию скрипта PowerShell?

    @MaxKozlov Куратор тега PowerShell
    Какой правильный способ для того, чтобы каждые 5 минут этот скрипт перезапускался, создавая новый файл, оставляя старые файлы?

    Вам именно надо чтобы скрипт перезапускался с самого начала или просто каждые 5 минут начинал писать в другой файл ?

    Потому что "перезапускался" несовместимо с "Запускать задачу при входе пользователя в систему"
    Ну или можно просто запускать с текущим пользователем каждые 5 минут. понятно, что пока пользователь не залогинился, запускать и не получится. Чтобы задача не плодилась, есть настройки "прибивать текущую" в шедулере

    *-Job - вообще не для этого
    А вот Add-Content, как раз, хорошо подойдёт для дописывания логов
    Ответ написан
    6 комментариев
  • Как правильно удалить определенные учетные записи windows 10 через powershell?

    @MaxKozlov Куратор тега PowerShell
    в цикле
    Удалить папку и соответствующую папке запись в реестре в
    "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList"

    Естественно, включая всякие проверки на системные папки типа Default/AllUsers, RefCount, соответствие guid и т.д.
    Те папки, которые в реестре не числятся и не являются системными - можно просто удалять

    А простого способа, насколько я знаю, нет

    Ну или можно поискать соответствующие модули
    Ответ написан
    Комментировать
  • Powershell не хочет распарсивать Json. Как правильно его распарсить или же добавить кавычки перед распарсиванием?

    @MaxKozlov Куратор тега PowerShell
    Вы можете предварительно через -replace заменить все эти сомнительные места на то, что вам надо, но в целом я согласен с Everything_is_bad, если вы собрались читать json, он должен быть валидным
    Ответ написан
    Комментировать
  • Как отправить письмо в Powershell без шифрования логина и пароля?

    @MaxKozlov Куратор тега PowerShell
    У вас и так пароль уходит на сервер в нешифрованном виде.

    То, что вы предварительно credential типа "шифруете" всё равно до сервера в таком виде не уходит. Оно только в памяти так хранится.
    в SMTP сессии там всё равно Plain/Login

    Можно отправлять через System.Net.Mail.SmtpClient

    пример

    Там с SSL всё гибче
    Ответ написан
    Комментировать
  • Почему powershell выдаёт разные результаты на команду из консольного ввода и из ScriptProperty?

    @MaxKozlov Куратор тега PowerShell
    Самое простое, если вас не устраивает Get-IniContent - поправить его, чтобы не путал :)
    ...
    $ini = [ordered]@{}
    ...
    $ini[$section] = [ordered]@{}
    ...


    Или взять класс на c# Отсюда
    и вкрячить его в свой powershell скрипт
    Ответ написан
    Комментировать
  • Как исправить ошибку кодировки Powershell, при выводе InvokeRequest?

    @MaxKozlov Куратор тега PowerShell
    Короче, полез таки я повторить ваш запрос
    На заголовки посмотрел до того не очень внимательно

    Тут на самом деле проблема не кодировки в смысле клиента (charset), а encoding для протокола - в смысле алгоритма компрессии. По короткому кусочку вывода это было не очень понятно, а выполнили ли вы рекомендацию записать в файл и там посмотреть - не ответили.

    Проблема в том, что PSv5.1 не умеет декодировать контент в том виде как вы его просите, а именно
    "accept-encoding"="gzip, deflate, br, zstd"
    PSv5.1 умеет в gzip, deflate, zstd. а вот в br не умеет

    Варианты:
    1. Используйте PSv7, он умеет
    2. Уберите 'br' из заголовка accept-encoding запроса
    3. Уберите вообще заголовок accept-encoding из запроса
    Ответ написан
    Комментировать
  • Ошибка Get-WmiObject: Не поддерживается, как исправить?

    @MaxKozlov Куратор тега PowerShell
    Работа WMI в общем случае не зависит от версии Powershell
    Скорее всего у вас сама база WMI поломана
    Можно попробовать "открыть" этот класс через wbemtest
    Если откроется с проблемами, попробовать починить базу wmi
    Примерно как здесь описано

    А может быть дрова не поддерживают, но это маловероятно
    Ответ написан
  • Как грамотно реализовать на PowerShell?

    @MaxKozlov Куратор тега PowerShell
    Какой ответ вы ждёте ?

    Я встречал в своей практике и чисто на скриптах и как отдельное приложение на C# (с возможностью запуска всё тех же скриптов для работы с exchange)

    Мой вариант ответа - можно. Но скрипт будет большой и сложный.

    С учётом необходимости создавать учётки там, где они сами не создаются, тот или иной вид скриптов всё равно понадобится.

    Делать это средствами только скриптов, или использовать, например, какие-то прослойки в виде очередей или серверов sso - на ваш вкус и опыт писания/настройки всего промежуточного.

    Только, на мой взгляд, БД здесь лишний элемент. Точнее, БД имеет смысл, только если запросы в AD для вас окажутся слишком дорогими (при большом количестве сотрудников)
    Ответ написан
    Комментировать
  • Как в Powershell загрузить изображение в переменную и освободить файл?

    @MaxKozlov Куратор тега PowerShell
    Используйте FromStream
    $content = Get-Content -Path "C:\temp\logo.jpg" -Encoding byte
    $ms = New-Object System.IO.MemoryStream
    $ms.Write($content)
    $img = [System.Drawing.Image]::FromStream($ms)
    Ответ написан
    2 комментария
  • Как сформировать регулярное выражение из 5 символов для вывода?

    @MaxKozlov Куратор тега PowerShell
    Может так ?

    $ou -split ',?..=' -split { }

    Нигде ведь не сказано, что сплит должен быть один. И регулярка одна на 5 символов
    Ответ написан
    4 комментария
  • Как из одной формы открыть файл содержащий другую форму?

    @MaxKozlov Куратор тега PowerShell
    Если у вас в другом файле просто создание формы, вы просто можете вызвать скрипт через "here syntax"
    типа . /Path/With/Form.ps1
    После вызова в вашем пространстве будут доступны все необходимые переменные
    и, когда понадобится, вы в коде просто вызываете эту форму

    Form2.ps1
    $Form2 = ...
    ...


    Form1.ps1
    $Form1 = ...
    ...
    .  .\Form2.ps1
    $button.add_click{
      $Form2.ShowDialog()
    }
    $Form1.ShowDialog()


    Но я бы на вашем месте уже ушёл бы на c# :)
    Ответ написан
    Комментировать
  • Почему не появляется скрытый comboBox?

    @MaxKozlov Куратор тега PowerShell
    Вы не повесили свой код на событие, вы его просто написали в произвольном месте скрипта

    Пример, как вешать на событие
    # Это код, который будет выполняться по событию и присвоение его переменной
    $radioButton1_OnClick = {
      $comboBox.Visible = $radioButton1.Checked
    }
    # Это подписка на само событие. Событие OnClick, выполняемый код из $radioButton1_OnClick
    $radioButton1.add_Click($radioButton1_OnClick)
    $radioButton2.add_Click($radioButton1_OnClick)
    Ответ написан
    8 комментариев
  • Как сделать чтобы тема с обычного Power Shell была в терминале VS Code?

    @MaxKozlov Куратор тега PowerShell
    Как именно ставили тему? Вот примерно так же. Через профили терминала
    Ответ написан
  • Как занести в таблицу БД наименование компьютера, наименование ОС сопоставимому IP-адресу компьютера?

    @MaxKozlov Куратор тега PowerShell
    Если у вас рабочий DNS, вам достаточно использовать
    [System.Net.Dns]::Resolve

    PS > [System.Net.Dns]::Resolve('8.8.8.8')
    
    HostName   Aliases AddressList
    --------   ------- -----------
    dns.google {}      {8.8.8.8, 8.8.4.4}


    то есть ваше имя компа будет определяться как
    [System.Net.Dns]::Resolve($ip).HostName
    Ответ написан
    1 комментарий
  • Kак сделать многопоточный PS-скрипт?

    @MaxKozlov Куратор тега PowerShell
    Самое простое - Start-Job, оно есть везде, начиная с 3.0
    но оно памяти жрёт и использует процессы, а не потоки. по быстрому, на десяток-другой компов - сойдёт.

    Многопоточное:
    • PoshRSJob (причём лучше мой форк ;)
    • ThreadJob
    • Invoke-Parallel


    Всё это (модули/скрипты) требует установки на админский комп для запуска задач в стиле
    $computers | Start-RSJob { Invoke-MyCommand -Computer $_ }

    Потом можно посмотреть результаты работы
    Get-RSJob | Receive-RSJob

    а уже внутри Invoke-MyCommand будет выполняться что-то, что лезет удалённо и делает там свои дела
    Но вот это Invoke-MyCommand - если это внешняя функция, а не просто набор действий, требует дополнительного "проталкивания" в поток. Примеры есть

    Другие модули работают аналогично, со своими нюансами, естественно
    Ответ написан
    4 комментария
  • Ошибка определения переменной powershell, в чем причина?

    @MaxKozlov Куратор тега PowerShell
    Ну вы введите прямо в PS
    $csvData = Import-CSV -Path C:\share\FII.csv -Delimiter "," -Encoding UTF8
    $csvData[0]."ФамилияИмя"

    Если там что-то будет, то пойти дальше
    Get-ADUser -Filter { DisplayName -eq $csvData[0]."ФамилияИмя" }


    А если нет - то ванга подсказывает, что может быть проблема с кодировкой файла и стоит посмотреть, что вообще выдаст $csvData[0]

    проблема действительно была в кодировке , при запросе выдавались крокозябры
    Ответ написан
    Комментировать
  • Add-LocalGroupMember где ошибся?

    @MaxKozlov Куратор тега PowerShell
    Попробуйте добавлять не имя, а результат new-localuser или get-localuser, раз уж создан


    MaxKozlov, спасибо помогло добавление еще одной переменной после создания пользака и запихивания туда выхлопа Get-LocalUser -Name $name.

    чертовски странно но оно работает ))

    $name = hostname
    $pass = ConvertTo-SecureString "1234567" -AsPlainText -Force

    #Создаем пользака sysadmin
    New-LocalUser -Name sysadmin -PasswordNeverExpires -Password $pass
    Add-LocalGroupMember -Group Администраторы -Member sysadmin
    Add-LocalGroupMember -Group "Пользователи удаленного рабочего стола" -Member sysadmin

    #echo "$name"

    #Создаем пользака с именем компа
    New-LocalUser -Name $name -PasswordNeverExpires -Password $pass
    $login = Get-LocalUser -Name $name
    #echo "$login"
    Add-LocalGroupMember -Group Администраторы -Member $login
    Add-LocalGroupMember -Group "Пользователи удаленного рабочего стола" -Member $login


    А работает оно так потому что
    >Get-Help Get-LocalUser -Full
    ...
    ВЫХОДНЫЕ ДАННЫЕ
        System.Management.Automation.SecurityAccountsManager.LocalUser[]
            This cmdlet returns local user accounts.
    
    >Get-Help Add-LocalGroupMember  -Full
    ...
    ПАРАМЕТРЫ
        -Member <Microsoft.PowerShell.Commands.LocalPrincipal[]>
            Specifies an array of users or groups that this cmdlet adds to a security group. You can specify users or groups by name, security ID (SID), or LocalPrincipal objects.

    При этом
    >$lu = Get-LocalUser Administrator
    >$lu.GetType()
    Microsoft.PowerShell.Commands.LocalPrincipal
    >$lu.psobject.typenames
    Microsoft.PowerShell.Commands.LocalUser
    Microsoft.PowerShell.Commands.LocalPrincipal

    LocalUser - наследник LocalPrincipal

    То есть, если в качестве Member передавать нативный объект, всё работает как часы
    А если строку, то эта строка неверно преобразуется в объект.
    Вот так легко создаётся LocalPricipal из имени компа.
    [Microsoft.PowerShell.Commands.LocalPrincipal]::new($env:COMPUTERNAME)

    Если залезть в исходники
    AddLocalGroupMemberCommand.cs
    Sam.cs
    То во второй ссылке есть вызов получения сида из имени. видимо, именно он при одинаковых вводных сначала запрашивает компы, а потом юзеров
    Ответ написан
    1 комментарий
  • Не выводятся значения пользователей AD через powershell, в чем причина?

    @MaxKozlov Куратор тега PowerShell
    Проблема в том, что
    $user = Get-ADUser -identity "i.tsebrenko"
    Возвращает только стандартные поля
    DistinguishedName
    Enabled
    GivenName
    Name
    ObjectClass
    ObjectGUID
    SamAccountName
    SID
    Surname
    UserPrincipalName


    Если вы хотите посмотреть именно DisplayName, надо его специально просить
    $user = Get-ADUser -identity "i.tsebrenko" -Property DisplayName
    Write-Host $user.DisplayName


    Кстати, если вот такая фильтрация вам внезапно вернёт двоих, скрипт упадёт
    #Фильтруем пользаков по схожему описанию в AD
    $User = Get-ADUser -Filter {Description -eq $userDescription}
    #Изменяем указанные поля полями из csv файлы , присваиваем значения через $row.значение_из_таблицы
    if ($User) {

    Тут надо этот момент отдельно обрабатывать. Мало ли, кто-то руками description поправит
    Ответ написан
    4 комментария