среда, 31 октября 2018 г.

PowerShell - Odd and Even numbers script

cls
# Odd and Even numbers script
# Gives Sum of odd, then even numbers and counts them, then compares.
# The result come in form of one line with headers.

$InputFile = "D:\SCRIPT\input-output\input.txt"
$OutputFileOdd = "D:\SCRIPT\input-output\OddArray.csv"
$OutputFileEven = "D:\SCRIPT\input-output\EvenArray.csv"
$OutputFileArray = "D:\SCRIPT\input-output\NumbersArray.csv"
$Content = Get-Content $InputFile
# The following line is for creating an empty array.
# @()

# The following line is for creating array of numbers in place.
# [int[]] $NumbersArray = 0 .. 10

# Following is zeroing of variables.
$Flag = 0
$OddCount = 0
$OddSum = 0
$EvenCount = 0
$EvenSum = 0
$OddArrayCount = 0
$EvenArrayCount = 0
$Sum = 0
$Count = 0

# This array is usable in case of creating multi-line Excel but it's not our case.
# $CSVArray = New-Object System.Collections.ArrayList

# The following lines create arrays for odd and even numbers.

$OddArray = New-Object System.Collections.ArrayList
$EvenArray = New-Object System.Collections.ArrayList

# The cycle finds the remainder that help us to understand if the number is odd or even.
# Then odd and even arrays are filled up with odd and even numbers.
ForEach ($Number in $NumbersArray)
   {
            If ($Number -ne 0)        
        {
            $Remainder = $Number % 2
                   
            If ($Remainder -eq 0) { $Flag = "Even" } Else { $Flag = "Odd" }

            If ($Flag -eq "Odd")
            {
                $OddArrayNumber = New-Object -Type PSObject
                $OddArrayNumber | Add-Member -MemberType NoteProperty -Name "Odd" -Value "$Number"
                $OddArray.Add($OddArrayNumber)
                $OddCount = $OddCount + 1
                $OddSum = $OddSum + $Number
            }       
            If ($Flag -eq "Even")
            {
                $EvenArrayNumber = New-Object -Type PSObject
                $EvenArrayNumber | Add-Member -MemberType NoteProperty -Name "Even" -Value "$Number"
                $EvenArray.Add($EvenArrayNumber)
                $EvenCount = $EvenCount + 1
                $EvenSum = $EvenSum + $Number            
            }
            $Count = $Count + 1
            $Sum = $Sum + $Number 
        }               
        $Flag = 0
   }
       $OddArray | Export-Csv $OutputFileOdd -NoTypeInformation
       $EvenArray | Export-Csv $OutputFileEven -NoTypeInformation

       $OddArrayCount = $OddArray.Count
       $EvenArrayCount = $EvenArray.Count

# New object $ArrayLine is created in every loop for Excel line.
# It fills up with count and sum for odd and even numbers.
$ArrayLine = New-Object -Type PSObject
$ArrayLine | Add-Member -MemberType NoteProperty -Name "OddArrayCount" -Value "$OddArrayCount" -Force
$ArrayLine | Add-Member -MemberType NoteProperty -Name "OddCount" -Value "$OddCount" -Force
$ArrayLine | Add-Member -MemberType NoteProperty -Name "OddSum" -Value "$OddSum" -Force

$ArrayLine | Add-Member -MemberType NoteProperty -Name "EvenArrayCount" -Value "$EvenArrayCount" -Force
$ArrayLine | Add-Member -MemberType NoteProperty -Name "EvenCount" -Value "$EvenCount" -Force
$ArrayLine | Add-Member -MemberType NoteProperty -Name "EvenSum" -Value "$EvenSum" -Force

$ArrayLine | Add-Member -MemberType NoteProperty -Name "SUM" -Value "$SUM" -Force
$ArrayLine | Add-Member -MemberType NoteProperty -Name "COUNT" -Value "$COUNT" -Force

# Adding values to two-dimensional array for output to Excel.
# $CSVArray.Add($ArrayLine) | Out-Null
$ArrayLine | Export-Csv $OutputFileArray -NoTypeInformation

Write-Host Flag = $Flag
Write-Host OddCount = $OddCount
Write-Host OddSum = $OddSum
Write-Host EvenCount = $EvenCount
Write-Host EvenSum = $EvenSum

Write-Host OddArrayCount = $OddArrayCount
Write-Host EvenArrayCount = $EvenArrayCount
Write-Host General SUM = $SUM
Write-Host General COUNT = $COUNT
Write-Host "The job is Done"
Write-Host ""

понедельник, 29 октября 2018 г.

Computer Uptime или сколько времени работает ваш компьютер

Сначала мы рассмотрим, как определить время на локальном компьютере, а затем на удаленном. 
Метод #1 - Task Manager
В Windows 10 кликаем на Taskbar, затем 

суббота, 27 октября 2018 г.

Time Changing

Да, прямо сейчас я сижу на работе и слушаю музыку, а время 3 ночи.
Почему бы это так? Ах да, сегодня смена времени - злобные силы решили подарить нам лишний час.

Net Time or w32time ?

Вы все, наверное, знаете, что для проверки и настойки времени на компьютерах Windows используются две команды: Net Time и w32time. Вопрос, в чем между ними разница и когда использовать каждую из них.

w32time расшифровывается как Windows Time Service. Это сервис, который бежит на большинстве Windows компьютеров, начиная с Windows 2000. Он состоит из сервиса времени (w32time) и пользовательского приложения w32tm.exe для управления и мониторинга. Сервис использует UDP порт 123 и синхронизируется при помощи протокола NTP.

NET TIME, а точнее приложение net.exe, использует библиотеку NetApi32.dll. Работа со временем лишь одна из множества функций net.exe. Для доступа к удаленным компьютерам net.exe использует RPC, а не NTP. По этой причине NET TIME релевантен и сегодня, хотя родился он еще до эпохи Win 2000. Правда, с другой стороны,  UDP 123 редко блокируется, что является плюсом.

Если нужно выяснить "исправность" времени сразу на нескольких компьютерах, можно использовать простейший batch-файл, который может выгляеть таким образом:

NET TIME \\Server1
NET TIME \\Server2
NET TIME \\Server3

среда, 24 октября 2018 г.

Logoff remote User


Иногда, особенно в большой сети, некий сервер может стать недоступным для входа при помощи, скажем, RDP (Remote Desktop Protocol).
Обычно, причина для этого, количество залогиненных пользователей, которое превышает два.  

Существуют инструменты командной строким которые удаленно способны решить проблему.
Rwinsta
Qwinsta
Quser
Logoff
Query Session


First, check the session number with qwinsta:

QWINSTA /server:YOURCOMPUTERNAMEHERE
Write down the session ID.

Then use the logoff command:

LOGOFF YOURSESSIONIDHERE /server:YOURCOMPUTERNAMEHERE


CMD Tips-n-Tricks или "полезняшки" командной строки

Как получить DATE и TIME в командной строке?
date /t и echo %date% дают одинаковый результат, хотя и работают по-разному - как команда и как переменная окружения (environment variable).

Более старые рекомендации:
ECHO. |TIME > TIME
COPY LOG.TXT +TIME

---START---
@echo offset log=C:\temp\program.log
echo I am starting for you program.exe at %date% %time% >> %log%
program.exe >> %log%
echo. |time |find "current" >> log.txt
---END---

Если нужно вывести время начала работы какой либо программы в log-файл:


среда, 17 октября 2018 г.

Как добавить Exchange PowerShell module в сессию

Как добавить Exchange PowerShell module в сессию

Как добавить Exchange PowerShell module в стандарную сессию PowerShell?Короткий ответ следует ниже. Полный ответ следует далее.
Exchange 2007Add-PSSnapin Microsoft.Exchange.Management.PowerShell.Admin
Exchange 2010Add-PSSnapin Microsoft.Exchange.Management.PowerShell.E2010
Exchange 2013 2016Add-PSSnapin Microsoft.Exchange.Management.PowerShell.SnapIn

Далее описывается метод добавления Exchange Management Shell в ISE. Компоненты, которые мы используем для этого такие:

- ISE console
- ISE PowerShell profile
- PowerShell script, который загружается в Exchange Management Shell.

- Exchange Management Tools должны быть установлены на вашем компьютере.(Setup.exe /Role:ManagementTools /IAcceptExchangeServerLicenseTerms)

Если есть проблема во время инсталляции
The following error was generated when "$error.Clear();
if($RoleInstallWindowsComponents){# Install any Windows Roles or Features required for the Management Tools role
Install-WindowsComponent -shortNameForRole "AdminTools" -ADToolsNeeded $RoleADToolsNeeded}"
was run: "The system cannot find the file specified".

   Open Control Panel, and then select Programs.
    Click Turn Windows features on or off.
    Select Microsoft .NET Framework 3.5.1.
    Navigate to Internet Information Services > Web Management Tools > IIS 6 Management Compatibility.
    Select the check box for IIS 6 Management Console, and then click OK.
    Restart you PC
    Install Exchange admin tools

That should do the trick.

вторник, 16 октября 2018 г.

Partition Managers

MiniTool Partition Wizard Home Edition

AOMEI Partition Assistant Home

EaseUS Partition

MasterParagon Partition Manager Free Edition

Partition Magic

Ranish Partition Manager

Partition LogicGParted 

Отмена warning message в Office при открытии EXE файла

Исходные данные - Office 2010, Windows 7.

Ситуация такая - экран компьютера засорен множеством ярлыков на программы. Мне показалось, что имеет смысл сделать примитивный application launcher на основе Excel.
Нажимаешь на ячейку, которая является Hyperlink к исполняемому файлу (exe, com, bat) и программа включается.
Другие поля могут служить названиями программ и комментариями. В Excel это может выглядеть достаточно удобно и не требует особых навыков - каждый может такое сделать.

Так и было сделано. И все бы хорошо, но один момент мне не давал покоя. Когда я нажимал на Hyperlink программа открывалась, но с предупреждением о возможном вирусе, после чего нужно было нажимать на OK. Причем, программы располагались на сетевом диске.
После недолгих поисков в интернет я нашел несколько решений, но они не работали. Все, кроме одного. Вот оно.

Modify the HKEY_CLASSES_ROOT\\EditFlags registry subkey

Use this method if the warning message affects multiple computers. 
To disable the warning message, follow these steps:
  1. Click Start, click Run, type regedit, and then click OK
  2. Locate the following registry subkey: 
    HKEY_CLASSES_ROOT\\EditFlags
    For example, if the file name extension is WMV, select HKEY_CLASSES_ROOT\WMVFile\EditFlags
  3. Click EditFlags, and then click Rename on the Edit menu.
  4. Type OldEditFlags, and then press ENTER.
  5. On the Edit menu, point to New, and then click DWORD value.
  6. Type EditFlags, and then press ENTER.
  7. On the Edit menu, click Modify.
  8. In the Edit DWORD Value dialog box, click Hexadecimal under Base.
  9. Type 10000, and then click OK.

Как открыть папку, файл или программу из командной строки CMD?

Вопрос, вроде бы, элементарный?
Но иногда в экстренный момент нужен ответ, а он не подворачивается.
Ответ простой - команда Start.

Примеры на открытие папки (folder, directory):
start C:
start C:\Windows
Можно и так:
start explorer C:
start explorer C:\Windows
однако первый способ быстрее в открытии и проще в написании.

Примеры на открытие файла:
start c:\file.txt (при условии, что такой файл существует)
start c:\file.doc

Примеры на открытие программы:
start calc
start notepad
start winword

Можно также открыть программу с файлом в качестве параметра:
start winword c:\file.doc
Однако у такого способа нет преимущества перед способом без указания открывающей программы, за исключением случая, когда нужно использовать нестандартную программу (ту, которая не является дефолтивной).

А что, если нужно открыть серию папочек на удаленном компьютере в локальной сети?
И делать это регулярно. Тогда лучше включить команды в batch-файл, например такой:
:===START===
@echo off
start \\Server1\C$
start \\Server1\C$
start \\Server1\C$
EXIT /B
:===END===

Для открытия локальных или удаленных папок есть интересная команда Pushd. 
Она, по сути, не открывает папки, а создает сетевые диски. Для локального компьютера можно использовать такую команду:

pushd \\localhost\C$
 
Обратите внимание на две вещи:
- Pushd автоматически создает сетевые диски, начиная с буквы Z: и далее в обратную сторону,
Pushd автоматически перемещает вас на созданный сетевой диск.
Это верно, даже если вы создаете диск для папки в глубине файловой системы:
По сути, команда сействует аналогично старинной команде Subst, но не локально, а по сети.

Да, а что же насчет сетевых дисков для удаленных компьютеров, ведь наши примеры касались только локального компьютера? Очень просто: localhost заменяем на имя удаленного компьютера:
pushd \\Server1\C$










четверг, 11 октября 2018 г.

Как убить процесс или сервис. How to kill process or service.

Иногда возникает задача "убийства" нежелательного процесса или сервиса.
Но, прежде всего, надо прояснить различие между понятиями процесс, сервис и аппликация (программа).

Основа всего процесс - он является основой для сервисов и аппликаций и выполняет exe файл. В типичных случаях дело обстоит следующим образом:

- аппликация - это процесс с окошком или программа, с которой мы можем взаимодействовать,
- сервис - это процесс, не имеющий окна, т.е., работающий "скрытно". Кроме того признаком сервиса является его свойство выдерживать logoff.

Однако все это не строго обязательно - существуют процессы, которые не являются ни севисами, ни аппликациями, например, драйверы некоторых устройств. С другой стороны, существуют аппликации, основанные на сервисах.

Подробное объяснение займет больше места, но для наших целей этого достаточно.

Убийством можно заниматься при помощи различных "орудий": Net, Sc, Taskkill, PSKill, Wmic, PowerShell (to name some). 

Для остановки/поднятия сервиса (звучит мягче, чем убийство ?) чаще используют команды Net и Sc.
net stop spooler
net start spooler
Аналогично:
sc stop spooler
sc start spooler
Разница между net и sc нас пока не занимает.

Нужно заметить, что spooler является сервисом, основанном на процессе с именем spoolsv.exe.

Поэтому, если есть потребность убить процесс как процесс, придется использовать другое имя. 

Для чего может понадобиться убивать процесс, если достаточно опустить сервис? 

Резон для этого таков, что процесс может не захотеть опускаться или может застрять в процессе опускания.

Сначала путь для простого пользователя:

Включаем services.msc, находим сервис и определяем его реальное имя.
Затем идем в CMD, пишем sc queryex [servicename] и замечаем PID процесса.
Не выходя из CMD пишем taskkill /pid [pid_number] /f
После нажатия на Enter дело сделано. 

Вместо PID процесса можно использовать его имя, для этого достаточно использовать параметр /im: taskkill /im [process_name] /f

Кажется, что так удобнее, ведь имя процесса "человечнее" и узнать его легче, чем PID. Кроме того, имя не меняется при каждом запуске процесса, в отличие от PID и его легче заложить в Batch файл.
Проблема метода в том, что так убиваются все процессы с соответствующим именем. С другой стороны, иногда это как раз необходимо, как в случая с Chrome, который на каждое окошко открывает отдельный процесс, кушая при этом много памяти, а опустить все его инстансы (instances) по PID вручную может быть затруднительно. 

И здесь очень поможет следующая команда: 

taskkill /im chrome.exe /f
Просто приятно было наблюдать все эти десятки процессов-окошек, закрывающихся на глазах изумленного себя.:)

Теперь поставим такую задачу. Мы хотим сначала попробовать закрыть процесс , а в случае неудачи применить силу. Вначале придется определить состояние процесса (чтобы не выдавалась ошибка), а затем попытаться закрыть его двумя способами.  

В качестве примера возьмем Spooler, ответственный за печать. Он безопасен для системы и является примером процесса-сервиса.

Если Spooler поднят, tasklist выдаст errorlevel 1, а если опущен - errorlevel 0.
Теперь попытаемся опустить Spooler при помощи net stop, а в случае неудачи применим taskkill.
::---Start
tasklist /fi "imagename eq spoolsv.exe" |find ":" > nul
if errorlevel 1 net stop "spooler"
if errorlevel 1 taskkill /f /im "spoolsv.exe"
::===END

Обратите внимание на различие в именах сервиса (spooler) и исполняемого файла (spoolsv.exe).

Обратите также внимание: не играет роли то, что проверка выполняется на сервис, а поднимаем мы процесс. Все работает. 

Для поднятия сервиса можно использовать следующий простой код:

::---Start
tasklist /fi "imagename eq spoolsv.exe" |find ":" > nul
if errorlevel 0 net start "spooler"
::===END

Если по какой-то причине вам нужно опустить и, затем, после паузы поднять сервис, воспользуйтесь известным способом, программой Ping:

::---Start
net stop spooler
ping 127.0.0.1 -n 10 -w 1000 > nul
net start spooler
::===END

Этот простой прием даст вам отсрочку в 10 секунд.


Ну, а когда закончите читать статью при помощи браузера Chrome, можете вместо Spooler использовать слово Chrome. Только поставьте значок комментария перед строчкой net stop, т.к., этот процесс является примером аппликации, не имеющей сервиса. 

Ок, я помогу...

::---Start
@echo off
taskkill /t /im chrome.exe /f
EXIT /B
::===END

Good luck!






среда, 10 октября 2018 г.

PoSH - Get-Process примеры

Get-Process | Sort-Object WorkingSet -Descending | select -First 5
Get-Service | Sort-Object WorkingSet, DisplayName -Descending | select -First 5
14,14,5,6,7,1,54,4,4,5,6,1,0,33,3,5 | sort -Unique
Get-EventLog Application -Newest 100 | sort Source -Unique

PoSH - Get-Service примеры

# Get-Service
get-service -displayname 'Background Intelligent Transfer Service'
get-service | where {($_.status -eq "Running") -and ($_.CanStop -eq $true)}
get-service | where {($_.status -eq "Running") -and !($_.CanStop -eq $true)} # Negation
get-service | ? { $_.status -eq 'running' -and ($_.canstop) }
get-service | ? { $_.status -eq 'running' -and !($_.canstop) } # Negation
Get-Service | Get-Member canstop

# Sort and Select:
Get-Service | Sort-Object WorkingSet,DisplayName -Descending  | select -First 5

PoSH - инсталляция модуля AD на Windows 7

# For Workstation
Get-Help *WindowsFeature
Import-Module ActiveDirectory
Get-WindowsFeature | where name -like RSAT-AD-PowerShell | Install-WindowsFeature

# For Server
Install-WindowsFeature
Install-WindowsFeature Desktop-Experience
Windows-identity-foundation
Import-Module ServerManager
Add-WindowsFeature RSAT-AD-PowerShell
gcm | ? { $_.ModuleName -eq 'ServerManager' }

PoSH - ScriptAnalyzer - Install, Check and Use

# Install PSScriptAnalyzer
Install-Module -Name PSScriptAnalyzer -Scope CurrentUser
Get-Module -Name PSScriptAnalyzer -ListAvailable
Import-Module -Name PSScriptAnalyzer

# Check PSScriptAnalyzer
Get-Command -Module PSScriptAnalyzer
Get-ScriptAnalyzerRule

#--- Use ScriptAnalyzer
$InvokePATH = & 'C:\Scripts\GoodScript.ps1'
Invoke-ScriptAnalyzer $InvokePATH

вторник, 9 октября 2018 г.

PoSH Tips-n-Tricks или "полезняшки"

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

Эта статья задумана как сборник различных "Tips-and-Tricks", которые, будучи собранными в одном месте, смогут напомнить вам (и мне) о существовании и способе применения различных команд, а также смогут помочь справиться с различными стандартными и нестандартными ситуациями.

В этом словаре-напоминалке не будет подробных объяснений команд, а параметры будут даны только самые необходимые - минималистский подход.

Надеюсь постоянно обновлять этот пост по мере встречи с различными явлениями и способами их решения.

-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
Measure-Object (измерения различных значений)
# Объем RAM компьютера в Mb:
(Get-WmiObject Win32_PhysicalMemory | Measure-Object Capacity -sum).sum/1mb

# К-во процессов на компьютере:
(Get-Process | measure VirtualMemorySize -Sum).count

# Объем памяти RAM, занятой всеми процессами, в Mb:
(Get-Process | measure VirtualMemorySize -Sum).sum/1mb

#---Start
# RAM, округленный до двух знаков после точки:
$VMMemSize = (Get-Process | measure VirtualMemorySize -Sum).sum/1mb
$VMMemSize2 = [math]::round($VMMemSize,2)
Write-Host "Rounded VMMemSize = $VMMemSize2 Mb"
#---Stop

# How to check where TEMP folder located:
$env:temp

# Размер папки TEMP:
(dir $env:temp | Measure-Object -Property length -sum).sum/1mb

#---Start
# Размер папки TEMP с округленным значением и коротким синтаксисом:
$FolderSize = (dir $env:temp | measure length -sum).sum/1mb
$FolderSize2 = [math]::round($FolderSize,2)
Write-Host Rounded RAM = $FolderSize2 Mb
#---Stop

Как проверить время работы скрипта - два способа.

#---START первый способ
Write-Host ""
$Timing1 = (Measure-Command { H:\Experiment\Get-WmiObject.ps1 }).totalseconds
Write-Host "Timing1 is $Timing1"
Write-Host ""
#---END первый способ

#---START второй способ (NET Stopwatch)
$sw = [Diagnostics.Stopwatch]::StartNew()
H:\Experiment\Get-WmiObject.ps1
$sw.Stop()
$Timing = ($sw.Elapsed).Milliseconds
Write-Host "Script was running $Timing Miliseconds"
Write-Host ""
#---END второй способ (NET Stopwatch)

Как проиграть звуковой файл из PowerShell? Да, это возможно!
$PATH = ’D:\Hey Jude.wav’
$PlayWav=New-Object System.Media.SoundPlayer
$PlayWav.SoundLocation=$PATH
$PlayWav.playsync()

Как пользоваться командами Get-WmiObject?

# Следующие 3 команды дают одинаковый результат - данные о BIOS компьютера:
Get-WmiObject -Class win32_bios -ComputerName $env:COMPUTERNAME
Get-WmiObject -Class win32_bios -ComputerName localhost
Get-WmiObject -Class win32_bios -ComputerName .

Как получить данные об удаленном компьютере?
Команда запрашивает имя/IP компьютера, вы его вводите - результат налицо!
(точка или localhost также принимаются в качестве ответа)
#---START
$ComputerName = Read-Host -Prompt "Enter computer name or IP"
Get-WmiObject -Class win32_bios -ComputerName $ComputerName
#---END

# Как проверить, какая версия PoSH установлена - 32 или 64 bit?
[Environment]::Is64BitProcess

How to install NTFSSecurity module:
Get-Module -ListAvailable # (проверка имеющихся модулей)
Install-Module -Name NTFSSecurity

PoSH - эффективность команды Get-ADComputer

Предположим, нам нужно получить данные о серверах домена Active Directory при помощи команды Get-ADComputer. Как быстрее и эффективнее выполнить команду?
Приведу несколько примеров в скрипте, который измеряет время выполнения 6 различных вариантов команды.

#---START
Clear-Host
$startTime = (Get-Date)
Get-ADComputer -Filter {OperatingSystem -Like '*Server*'} | Select-Object -expand Name | Out-Null
$endTime = (Get-Date)
$ElapsedTime1 = ($endTime-$startTime).ToString('''Duration: ''mm'' min ''ss'' sec''')
Write-Host "Duration of the operation 1: $ElapsedTime1"
Write-Host ""

$startTime = (Get-Date)
Get-ADComputer -Filter * | Where-Object OperatingSystem -Like '*Server*' | Select-Object -expand Name | Out-Null
$endTime = (Get-Date)
$ElapsedTime2 = ($endTime-$startTime).ToString('''Duration: ''mm'' min ''ss'' sec''')
Write-Host "Duration of the operation 2: $ElapsedTime2"
Write-Host ""

$startTime = (Get-Date)
Get-ADComputer -Filter {OperatingSystem -Like '*Server*'} -Properties * | Select-Object -expand Name | Out-Null
$endTime = (Get-Date)
$ElapsedTime3 = ($endTime-$startTime).ToString('''Duration: ''mm'' min ''ss'' sec''')
Write-Host "Duration of the operation 3: $ElapsedTime3"
Write-Host ""

$startTime = (Get-Date)
Get-ADComputer -Filter * | Select-Object -expand Name | Out-Null
$endTime = (Get-Date)
$ElapsedTime4 = ($endTime-$startTime).ToString('''Duration: ''mm'' min ''ss'' sec''')
Write-Host "Duration of the operation 4: $ElapsedTime4"
Write-Host ""

$startTime = (Get-Date)
Get-ADComputer -Filter * -Properties * | Where-Object OperatingSystem -Like '*Server*' | Select-Object -expand Name | Out-Null
$endTime = (Get-Date)
$ElapsedTime5 = ($endTime-$startTime).ToString('''Duration: ''mm'' min ''ss'' sec''')
Write-Host "Duration of the operation 5: $ElapsedTime5"
Write-Host ""

$startTime = (Get-Date)
Get-ADComputer -Filter * -Properties * | Select-Object -expand Name | Out-Null
$endTime = (Get-Date)
$ElapsedTime6 = ($endTime-$startTime).ToString('''Duration: ''mm'' min ''ss'' sec''')
Write-Host "Duration of the operation 6: $ElapsedTime6"
Write-Host ""
#---END


Operation1 - чемпион скорости, занимает долю секунды, ведь мы сразу выбираем только серверы.
Operation2 - занимает чуть больше секунды, т.к. сначала выбираются все компьютеры домена и только позже происходит отбор серверов.
Operation3 - около 13 сек.. Хотя отбор серверов происходит вначале, как и в $SRV1 (т.е., серверов мало), но затем вместо 9 базовых у них берутся все свойства, которых больше 70.
Operation4 - время больше секунды, как и в $SRV2. В обоих случаях первоначально выбираются все компьютеры со стандартными свойствами. Различие лишь в том, что в данном случае не присходит отбор серверов (что чуть быстрее), хотя в переменную выводится больше имен (что чуть медленнее). Видимо, различия взаимно компенсируются, или же их влияние несущественно.
Operation5 - здесь сначала выбираются все компьютеры и у них берутся все свойства - это ДОЛГО -, а отбор серверов происходит на поздней стадии, что не уменьшает время. Правда, меньше времени тратится на запись в переменную (но это время минимально).
Operation6 - так же долго, как и в случае $SRV5 и это понятно: в обоих вариантах сначала выбираются все компьютеры и у них берутся все свойства. Ну, а отбор или отсутствие такового влияют незначительно.

Какие выводы можно сделать?
Во-первых, отбор (или уменьшение к-ва объектов) лучше делать в начале строки (т.е. слева), т.к. выгодно производить затратные операции над меньшим к-вом объектов.
Во-вторых, отбирайте только нужные свойства, иными словами, старайтесь как можно меньше использовать звездочку (*).
В-третьих, видно, что опрос Active Directory занимает гораздо больше времени, чем операции над объектами в памяти компьютера. Кстати, именно поэтому надо всегда стараться результат затратных операций выводить в переменные в случае необходимости повторного использования этих результатов.

воскресенье, 7 октября 2018 г.

PoSH - разница между Get-ADDomainController и Get-ADComputer

Мы имеем два похожих коммандлета: Get-ADDomainController и Get-ADComputer.
Кроме названий, которые selfexplained, есть также различие в синтаксисе и выводимых свойствах (properties).

9 стандартных свойств Get-ADComputer включают Name и DNSHostName (по сути, FQDN).
7 стандартных свойств Get-ADDomainController включают Name, Domain, Forest, IPv4Address.
Сразу видно, что из всего лишь семи свойств большая часть полезны, в отличие от менее полезных девяти (ИМХО). Для FQDN вместо DNSHostName используется название HostName (не знаю, почему).

Насчет полезности, Get-ADDomainController имеет очень нужное свойство IPv4Address. 
В Get-ADComputer мы можем его получить, но только в расширенных свойствах, для чего нужно объявить его в -Properties. Несложно, но зачем? Сравните, насколько короче строка в первом случае.
Get-ADDomainController -Domain domainname -Discover
Get-ADComputer -Identity computername -Server domainname/dcname -Properties Name,IPv4Address

Обратите внимание на две особенности: для одинаковой цели в первом случае используется имя параметра -Domain, а во втором -Server. Интересно также, что -Server принимает как domainname, так и dcname (имя контроллера домена). Все это поначалу немного путает, не так ли? 

В общем, как мне кажется, коммандлет Get-ADDomainController более продуман и логичен. Видимо, для своих старались :)

Не забудем, также, что для Get-ADComputer мы не обязаны применять параметр -Identity, можно использовать -Filter, главное, чтобы один из них присутствовал. Напомню, что -Identity применяется для указания одной сущности (компьютера), а -Filter для набора сущностей. 

И да, пока не забыл, в Get-ADComputer компьютер (-Identity computername) должен быть членом домена, указанного в параметре -Server (domainname/dcname), иначе будет ошибка. Что, впрочем, естественно. 


Несколько примеров для Get-ADComputer.

Get-ADComputer -Filter * # минимальная команда, которая дает список всех компьютеров текущего домена.

Get-ADComputer -Filter {OperatingSystem -Like "*Server*"} # выбираются все серверы текущего домена (того, где залогинен компьютер, с которого вы работаете).

Get-ADComputer -Filter * -Server domainname/dcname # благодаря параметру -Server можно получить список всех компьютеров нужного домена; нужно лишь указать имя домена или DC - домен контроллера требуемого домена.

Get-ADComputer -Filter {OperatingSystem -Like "*Server*"} -Server domainname/dcname # сочетание фильтра и имени DC/домена дает возможность получить список северов любого домена.

Get-ADComputer -Identity computername -Server domainname/dcname -Properties Name,IPv4Address # здесь указывается имя нужных компьютера и домена, нужно лишь следить за их правильным сочетанием.

Несколько примеров для Get-ADDomainController.

Get-ADDomainController # в отличие от предыдущего командлета команда работает без параметров и выдает сразу 24 свойства для одного из контроллеров текущего домена.

Get-ADDomainController -Domain domainname -Discover # так мы получаем свойства одного из DCs указанного домена. 

Get-ADDomainController -Filter * # способ получить все DCs - домен контроллеры текущего домена.

Get-ADDomainController -Filter * -Server dcname способ получить все DCs любого домена по имени сервера этого домена.

Get-ADDomainController -Filter * -Server domainname # это способ получить все DCs любого домена по имени домена (неважно, что параметр называется -Server - это работает).

Обратите внимание, что работают сочетания параметров  -Domain / -Discover или -Filter / -Server. 
Конечно, для вывода на экран удобнее использовать скобки, Format-Table (FT) или Select-Object (Select). 

Если достаточно показать только одно свойство - скобки ИМХО удобнее:
(Get-ADComputer -Filter *).Name 
В случае необходимости показа нескольких свойств - FT или Select:
Get-ADComputer -Filter * | FT Name,IPv4Address
Get-ADComputer -Filter * | Select Name
Select лучше работает, если вывод направляется не на экран, а в файл или пайп.

Надеюсь, что на сегодня информации достаточно.