Задать вопрос
Ответы пользователя по тегу PowerShell
  • Как открыть доступ к папке?

    @MaxKozlov Куратор тега PowerShell
    Во первых, кроме прав на диск, есть права на шару, на системную шару с правами туго.
    Во вторых, для такого простого скрипта копирования вам хватит robocopy, оно ещё и побыстрее будет

    Создаёте на первом сервере шару Backup$ - даёте на неё (на шару) права своей сервисной учётке.
    и robocopy с /MAXAGE копируете

    Можно, если хочется и скрипт оставить, но шару надо сделать
    Ответ написан
    Комментировать
  • Как отредактировать csv файл с помощью powershell?

    @MaxKozlov Куратор тега PowerShell
    Стоит проверить что именно у вас долгое
    Import-csv вы никак не ускорите.
    А вот $dataColl - реальный кандидат на ускорение
    Проще всего использовать ArrayList вместо массива
    ...
    $dataColl = New-Object System.Collections.ArrayList
    foreach  ($Path in $Paths){
    ....
        [void]$dataColl.Add($dataObject)
      }
    }
    ...


    И вообще, массивы для коллекционирования более 1000 элементов - тормоза, потому что они каждый раз пересоздаются и копируются из старого в новый.

    Measure-Command { $a = @(); 1..1000 | %{ $a += $_ } }
    
        TotalMilliseconds : 40,3721
    
    Measure-Command { $a = New-Object System.Collections.ArrayList; 1..1000 | %{ [void]$a.Add($_) } }
    
        TotalMilliseconds : 18,5863
    
    # А для 10000 уже
       TotalMilliseconds : 2016,3737
      vs
       TotalMilliseconds : 57,6177


    p.s. Кстати да, Роман Безруков верно заметил, что новый массив создавать вообще не обязательно. Но информация выше сильно влияет на работу, так что оставлю :)
    Ответ написан
    Комментировать
  • Как заменить старые файлы сравнивая их хэш и время создания?

    @MaxKozlov Куратор тега PowerShell
    Используете Compare-Object и Where-Object
    $oldfile = Get-FileHash .\old\*
    $newfile = Get-FileHash .\new\*
    Compare-Object $oldfile $newfile -Property Hash -PassThru | 
       Where-Object { $_.SideIndicator -eq '<='  } |
       Foreach-Object { Copy-Item $_.Path  -Destination $Destination }

    Не знаю что и куда вам копировать, поэтому в примере, может быть, придётся поменять условие при SideIndicator

    Для рекурсивного сравнения надо сбор хешей сделать рекурсивным :)
    $oldfile =  Get-ChildItem .\old\*  -Recurse | Get-FileHash
    $newfile = Get-ChildItem .\new\* -Recurse | Get-FileHash
    Ответ написан
    4 комментария
  • Как добавить кнопку Inline Keyboard в Телеграм вторым рядом, используя PowerShell?

    @MaxKozlov Куратор тега PowerShell
    если я правильно понимаю, вам надо передавать кнопки по строкам
    ..
    $row1 = @($buttonsubcheck, $buttonsubtrial)
    $row2 = @($buttonsubback)
    $buttonssub = ($row1, $row2)
    ..
    Ответ написан
  • Как можно в фоне отслеживать новые открываемые TCP подключения с помощью Powershell?

    @MaxKozlov Куратор тега PowerShell
    Судя по наличию соотвествующего события, отследить можно.
    Можно подписаться на это событие
    https://theposhwolf.com/howtos/PowerShell-On-Windo...
    https://stackoverflow.com/questions/36551151/how-t...
    И обрабатывать его наступление

    Ну или в цикле вызывать Get-NetTCPConnection
    И сравнивать с предыдущим списком с помощью Compare-Object
    Ответ написан
    1 комментарий
  • Как узнать пользователей, группы удаленного рабочего стола через powershell?

    @MaxKozlov Куратор тега PowerShell
    Я смотрю, вы не пошли по пути remote execution и вам хочется боли ? :)

    Тогда вот, берегите глаза
    $Computername = 'xxx'
    Get-CimInstance Win32_Group -filter "LocalAccount='True' and SID='S-1-5-32-555'" -ComputerName $Computername |
    Select-Object PSComputername,Name,@{Name="Members";Expression={
      (Get-CimAssociatedInstance -InputObject $_ -ResultClassName Win32_UserAccount).Name
    }}

    или в переводе на WMI
    $Computername = 'xxx'
    Get-WMIObject Win32_Group -filter "LocalAccount='True'and SID='S-1-5-32-555'" -ComputerName $Computername|
      Select-Object PSComputername,Name,@{Name="Members";Expression={
       $_.GetRelated("Win32_UserAccount").Name
    }}


    Здесь будут только пользователи. Для вложенных групп надо ещё подкрутить :)
    Upd:
    Ладно, не буду больше томить, нашёл альтернативный вариант
    Во времена PSv2 ещё написал, когда не было встроенной

    function Get-LocalGroupMember {
    param(
    	[Parameter(ValueFromPipeline=$false, Position=0)]
    	[string[]]$GroupName = 'Administrators',
    	[Parameter(ValueFromPipeline=$true)]
    	[string[]]$ComputerName = '.'
    )
    PROCESS {
    	foreach ($computer in $ComputerName) {
    		foreach ($group in $GroupName) {
    			$grp = [ADSI]"WinNT://$computer/$group,group"
    			Write-Verbose ('Group: ' + $grp.Path) # test for existance
    			$members = @($grp.psbase.Invoke("Members"))
    			if ($members) {
    				$members | Foreach-Object {
    					$name = $_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)
    					$class = $_.GetType().InvokeMember("Class", 'GetProperty', $null, $_, $null)
    					$parent = $_.GetType().InvokeMember("Parent", 'GetProperty', $null, $_, $null) -replace 'WinNT://' -replace '.*/'
    					'' | Select-Object @{n='Class';e={$class}},@{n='Domain';e={$parent}},@{n='Name';e={$name}}
    				}
    			}
    		}
    	}
    }
    }

    Только надо ещё знать имя группы, а оно может быть как на русском, так и на английском
    Пользоваться можно так, на один из вариантов ругнётся, по второму выдаст инфу

    Get-LocalGroupMember -ComputerName MySuperServer -GroupName 'Пользователи удаленного рабочего стола',  'Remote Desktop Users'
    Ответ написан
    2 комментария
  • Как перемещать файлы с заданными характеристиками?

    @MaxKozlov Куратор тега PowerShell
    Избавляться надо от ненужных преобразований типа $Paths = $Paths.FullName
    От вложенного цикла надо избавляться. N^2 однако. Если он там, конечно есть
    Так как нет примера того что у вас в csv, непонятно зачем он нужен вообще
    по тексту у вас вроде как во внешнем $Path должна быть уже просто строка
    Почему вы её ещё раз перебираете как foreach ( $Newpath in $Path) ?

    Ну и мувать с -Exclude *.xl* тоже странно, проще проверить на xl* в коде, чем заставлять этим заниматься move-item. Может быть, вы ps заставляете по новой весь каталог обшаривать таким образом, а в нём 10000 файлов xls

    Плюс, логи на каждый мув могут вас тормозить

    -Passthru на move-item излишен, он может заставлять по новой читать параметры файла с диска, а вам от него нужен только новый полный путь, который вы и так знаете

    А вообще я бы каталоги целиком таскал, по крайней мере на первом проходе.
    Судя по количеству ваших файлов, там большущая помойка.
    Ответ написан
    Комментировать
  • Как через powershell задать программу во вкладке среда пользователя AD?

    @MaxKozlov Куратор тега PowerShell
    Содержимое этой вкладки зашифровано в атрибуте
    userParameters
    Расшифровывать/Зашифровывать его муторно, поэтому если вам надо просто устанавливать его всем одинаковым, проще один раз его заполнить вручную, потом считать из AD, записать результат в файлик и впоследствии просто из файлика его присваивать. Или из другого юзера, как в примере.
    $referenceUser = Get-ADUser refuser -Property userParameters
    Set-ADUser targetUser -Replace @{
        userParameters = $referenceUser.userParameters
    }


    Для New-ADUser можно использовать -OtherAttributes
    Ответ написан
    2 комментария
  • Как в PowerShell подключить диск командой New-PSDrive на удаленном компьютере?

    @MaxKozlov Куратор тега PowerShell
    а если в том же самом Invoke-Command попытаться сделать, например, dir X: ?

    Диск вы подключаете от своего пользователя, а проверяете каким ?

    Подключение диска - оно индивидуально для пользователя

    Вообще, если вам для попользоваться, то в домене политиками диски подключают обычно
    Ответ написан
  • Как импортировать данные из Excel в MS SQL через Powershell?

    @MaxKozlov Куратор тега PowerShell
    Powershell сам никуда ничего не преобразовывает,
    Что ему отдаёт .Net - то и показывает
    с теми данными что вы показали у меня никто никуда ничего не меняет.
    Если кто-то и может менять, то драйвер экселя
    Ответ написан
  • Как сделать автоматический размер столбца USERNAME? И как скрыть от видимости последний столбец?

    @MaxKozlov Куратор тега PowerShell
    Ваши вопросы мало относятся к Powershell, это скорее .net
    гуглится примерно как c# listview column autosize,
    https://stackoverflow.com/questions/1257500/c-shar...
    c# listview column hide
    https://stackoverflow.com/questions/7811669/how-to...
    Ответ написан
    Комментировать
  • Как сделать так что бы при нажатии на вторую кнопку $dlgBttn.Text = 'View', было подключение к сессии на просмотр?

    @MaxKozlov Куратор тега PowerShell
    Точно так же. Только вместо /control - нужную команду
    И еще вы присваиваете одной переменной $dlgBttn обе кнопки. Поэтому по факту у вас работает только view. Сделайте разными
    Ответ написан
    2 комментария
  • Как можно определить перечень файлов и директорий с отсутствующий группой безопасности через Powershell?

    @MaxKozlov Куратор тега PowerShell
    $ar = New-Object System.Security.AccessControl.FileSystemAccessRule($group, @('Read', 'ReadAndExecute'), 
          'ContainerInherit,ObjectInherit', 'None', 'Allow')
    # Получаете список папок
    Get-ChildItem -Directory -Recurse $Path | Foreach-Object {
    # Получаете по ним ACL
      $acl = $_.GetAccessControl('Access')
    # Сравниваете с нужным
      if (-not ($acl.Access.IdentityReference -eq $group)) {
    # Добавляете если надо
        $acl.SetAccessRule($ar)
        $_.SetAccessControl($acl)
      }
    }

    upd: Поправил сравнение, так как для массивов на -eq происходит фильтрация, вынес создание $ar из цикла

    А вообще, как у вас могут появляться папки без нужных прав? Может права/наследование надо грамотно настроить ? Или скрипт на мониторинг создания папок повесить
    Ответ написан
    2 комментария
  • Как заставить Powershell прочитать звёздочку в имени Organizational Unit (OU)?

    @MaxKozlov Куратор тега PowerShell
    Потому что у PS (по крайней мере в версии 5.1) проблем с этим нет. Только что проверил

    UPD: Соврамши. именно пароль менять не хочет :) Остальное работает.

    Пока два варианта:
    1. Переместить запись в другой юнит, сменить там пароль и переместить обратно :)
    2. Использовать "старый" вариант с ADSI:
    $u = Get-ADUser iivanov
    $u2 = [ADSI]("LDAP://" + $u.DistinguishedName)
    $u2.SetPassword('PassWord123')


    Завтра на свежую голову ещё подумаю.
    Upd: Пожалуй, других вариантов нет.
    Powershell ActiveDirectory использует ActiveDirectoryWebServices, а не System.DirectoryServices, Похоже, это бага ADWS.

    Хотя, конечно, ситуация дикая
    Ответ написан
    1 комментарий
  • Как удалить .vhdx уволенных сотрудников?

    @MaxKozlov Куратор тега PowerShell
    Файлы удаляются через Remove-Item.

    Я бы написал так. Но, как справедливо указал Владимир Коротенко, на свой страх и риск :)
    $PathIn  = "\\Server\files"
    
    Get-ChildItem -Path $PathIn -Filter UVHD-S*.vhdx | Where-Object {
        $User = Get-AUser $_.BaseName.Substring(5);
        $User.Enabled -eq $false
    } | Remove-Item -Whatif

    И ещё, как минимум, стоит себя обезопасить и удалять не просто отключенных, на уже давно отключенных, например с просроченным паролем.
    То есть вам надо будет доработать часть $User.Enabled -eq $false
    Ответ написан
    2 комментария
  • Почему PowerShell не сообщает об отсутствии .dll файла?

    @MaxKozlov Куратор тега PowerShell
    Почему - не скажу, скорее всего особеность запуска именно из Powershell.
    Start-Process helloworld.exe
    Даст вам то же самое окно GUI с ошибкой
    А в самом PS можно смотреть на $LASTEXITCODE
    У меня туда на программу с отсутствующей dll возвращает 0xc0000135
    From the ntstatus.h SDK header file:

    //
    // MessageId: STATUS_DLL_NOT_FOUND
    //
    // MessageText:
    //
    // The program can't start because %hs is missing from your computer.
    // Try reinstalling the program to fix this problem.
    //
    #define STATUS_DLL_NOT_FOUND ((NTSTATUS)0xC0000135L) // winnt


    Хотя, скорее всего, это как раз окно с ошибкой - особенность запуска из Explorer, а cmd наверняка использует shell.open
    Ответ написан
    Комментировать
  • Почему значение accountexpires не совпадает со значением в gui?

    @MaxKozlov Куратор тега PowerShell
    Судя по всему, то что ставится в GUI AD - это последний день действия учётки.

    А вы используете сомнительный способ перевода числа в дату, мешает поправка на UTC, время вы отрезаете форматом и не видите разницу в временной зоне из-за этого

    Пример: Поставил в GUI дату как 04.10.2022
    Смотрим что в AD:
    Get-ADUser IIvanov -prop AccountExpirationDate, accountExpires
    AccountExpirationDate : 05.10.2022 0:00:00
    accountExpires        : 133093908000000000
    
    # Как делаете вы
    Get-Date 133093908000000000 -UFormat '%Y.%m.%d'
    0422.10.04
    
    # Что там на самом деле вы должны были увидеть
    Get-Date 133093908000000000
    4 октября 0422 г. 21:00:00
    
    # Как делаю я
    [datetime]::FromFileTime(133093908000000000)
    5 октября 2022 г. 0:00:00
    # Что великолепно совпадает с AccountExpirationDate, который я и рекомендую


    btw, установка переменной внутри where-object - лютый трэш :)
    Ответ написан
    Комментировать
  • Robocopy, копирование с разных хостов на сервер?

    @MaxKozlov Куратор тега PowerShell
    Самое простое в вашем случае, если запускаете сторонним софтом - обычный cmd
    .
    robocopy \\%computername%\c$\logs \\server\logs\%computername%\logs /e


    Если с сервера - powershell
    $computers =get-content 'c:\computers.txt'
    foreach ($computername in $computers) {
      robocopy "\\$computername\c`$\logs" "\\server\logs\$computername\logs" /e
    }

    Можно сделать подобный цикл на cmd через "for/f"
    for /f %%a in (c:\computers.txt) do robocopy \\%%a\c`$\logs \\server\logs\%%a\logs /e
    Ответ написан
    1 комментарий
  • Как в PowerShell преобразовать HEX в Double?

    @MaxKozlov Куратор тега PowerShell
    [System.BitConverter]::ToSingle(@(0xcd,0xcc,0x4c,0x41),0)
    12,8

    Соответственно, смотря откуда берёте данные.
    Если из массива байтов, то как написал выше, если из uint - сначала его предварительно надо тем или иным способом в массив байтов преобразовать. в целом это .net, а не powershell
    Ответ написан
    1 комментарий
  • Как найти ключ с нужным значением в реестре с помощью powershell?

    @MaxKozlov Куратор тега PowerShell
    Where-Object + GetValue()

    $usb = Get-ChildItem -path HKLM:\SYSTEM\ControlSet001\Enum\USB\ -Recurse
    $usb | Where-Object { $_.GetValue('Address') -eq 4 }


    Вообще, если вы используете свежий powershell с модулем PSReadLine, то автодополнение очень помогает

    $usb[1].<Ctrl+Space>
    И разглядываете
    или old-way
    Get-Member -InputObject $usb[1]

    Можно ещё заморочиться с Get-ItemProperty, но это будет сложнее
    Ответ написан
    Комментировать