Ответы пользователя по тегу PowerShell
  • Как можно в фоне отслеживать новые открываемые 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, но это будет сложнее
    Ответ написан
    Комментировать
  • Как передать переменную с локального компа на удаленный в сеанс powershell при выполнении psexec?

    @MaxKozlov Куратор тега PowerShell
    тут скорее зависит от того что у вас там в параметрах
    Что-то простое, типа строки, работает

    $x = 'test'
    psexec \\server powershell -NoProfile -Сommand "write-host '$X'"
    psexec \\server powershell -NoProfile -Command "param(`$a) write-host `$a"  $x

    А вот если там объект, его надо предварительно сериализовать в строку, а на той стороне десериализовать

    Вариант сериализации - Convert-ToJson с последующим упаковыванием в base64

    Может быть даже проще окажется использовать -EncodedCommand
    Ответ написан
  • Powershell - экранирование спецсимволов?

    @MaxKozlov Куратор тега PowerShell
    Честно говоря, живьём не пробовал, но, скорее всего нужно что-то типа того.
    Обратите ещё внимание, что Default в круглых скобках, а вокруг -Command кавычки не нужны

    New-ItemProperty -LiteralPath HKCR:\Microsoft.PowerShellScript.1\Shell\runas\command -Name '(Default)' -Value 'powershell.exe -NoExit -Command "if((Get-ExecutionPolicy ) -ne ''AllSigned'') { Set-ExecutionPolicy -Scope Process Bypass }; & ''%1''"' -PropertyType String -Force | Out-Null;

    Хотя, я не понимаю, зачем это надо :)
    Ответ написан
  • Как удаленно установить программу через powershell?

    @MaxKozlov Куратор тега PowerShell
    Enter-PSSession нельзя использовать в скриптах. Это интерактивная команда
    Вам нужно использовать
    Invoke-Command -ComputerName $computer { C:\Temp\Install.exe /S }

    Если выполнять несколько команд, можно создать сессию
    $session = New-PSSession -ComputerName $computer
    Invoke-Command -Session $session { C:\Temp\Install.exe /S }
    Invoke-Command -Session $session { C:\Temp\Install2.exe /S }


    Но тут может быть засада. Некоторые инсталляторы требуют интерактивную сессию

    Тогда придётся извращаться с запуском задачи от имени текущего пользователя, которая и будет выполнять вашу C:\Temp\Install.exe /S
    Ответ написан
    Комментировать
  • Powershell. Как правильно подставить значение переменной в URl адресс?

    @MaxKozlov Куратор тега PowerShell
    Можно просто вместо Select-Object id сделать Select-Object -ExpandProperty id
    Ответ написан
    Комментировать