Что вам нужно
Перед тем, как приступить к работе, есть некоторые инструменты и информация, которые вы должны иметь:
PowerShell
Этот скрипт был разработан с использованием PowerShell 4.0, а также был протестирован на совместимость с PowerShell 2.0. PowerShell 2.0 или более поздняя версия была встроена в Windows с Windows 7. Она также доступна для Windows XP и Vista как часть Windows Management Framework (WMF). Ниже приведены некоторые дополнительные сведения и ссылки для загрузки.
- PowerShell 2.0 поставляется с Windows 7. Пользователи Windows XP с пакетом обновления 3 (SP3) и Vista (SP1 или более поздние версии) могут загрузить соответствующую версию WMF от Microsoft в KB968929. Он не поддерживается на XP SP2 или ниже, или Vista без SP1.
- PowerShell 4.0 поставляется с Windows 8.1. Пользователи Windows 7 SP1 могут обновить его как часть обновления WMF из Центра загрузки Microsoft. Он недоступен для XP или Vista.
имена
Вам понадобятся некоторые списки имен для подачи в случайный генератор. Отличный источник для много имен и информации относительно их популярности (хотя это не будет использоваться для этого сценария), является Бюро переписи населения Соединенных Штатов. Списки, доступные по приведенным ниже ссылкам, очень велики, поэтому вы можете немного их обрезать, если планируете генерировать множество имен и номеров одновременно. В нашей тестовой системе каждая пара имен / номеров занимала около 1,5 секунд, чтобы генерировать полные списки, но ваш пробег будет зависеть от ваших собственных характеристик системы.
- Фамилии
- Мужчины Первые имена
- Женские первые имена
Независимо от источника, который вы используете, вам нужно создать три текстовых файла, которые сценарий может использовать в качестве пулов для выбора имени. Каждый файл должен содержать только имена и только одно имя для каждой строки. Они должны храниться в той же папке, что и ваш скрипт PowerShell.
Surnames.txt должен содержать фамилии, которые вы хотите выбрать из сценария. Пример:
Smith Johnson Williams Jones Brown
Males.txt должен содержать мужские имена, которые вы хотите выбрать из сценария. Пример:
James John Robert Michael William
Females.txt должен содержать имена женщин, которые вы хотите, чтобы сценарий выбирался. Пример:
Mary Patricia Linda Barbara Elizabeth
Правила для телефонов
Если вы хотите быть уверены, что ваши номера телефонов не соответствуют реальному номеру телефона, самым простым способом является использование известного кода обмена «555». Но если вы собираетесь показывать набор данных с большим количеством телефонных номеров, то 555 начнут выглядеть довольно монотонно реальными. Чтобы сделать что-то более интересным, мы будем генерировать другие номера телефонов, которые нарушают правила Нормы Северной Америки (NANP). Ниже приведены некоторые неверные номера телефонов, представляющие каждый класс числа, который будет сгенерирован этим скриптом:
- (157) 836-8167 Этот номер недействителен, потому что коды областей не могут начинаться с 1 или 0.
- (298) 731-6185 Этот номер недействителен, поскольку NANP не назначает коды областей с 9 в качестве второй цифры.
- (678) 035-7598 Этот номер недействителен, поскольку коды Exchange не могут начинаться с 1 или 0.
- (752) 811-1375 Этот номер недействителен, потому что коды Exchange не могут заканчиваться двумя 1 секундами.
- (265) 555-0128 Этот номер недействителен, поскольку код Exchange - 555, а также Идентификатор подписчика находится в пределах диапазона, зарезервированного для фиктивных номеров.
- (800) 555-0199 Этот номер является единственным номером 800 с кодом обмена 555, который зарезервирован для использования в качестве фиктивного номера.
Обратите внимание, что вышеуказанные правила могут быть изменены и могут варьироваться в зависимости от юрисдикции. Вы должны провести собственное исследование, чтобы проверить текущие правила, которые применимы к языку, для которого вы будете генерировать номера телефонов.
Общие команды
Есть несколько довольно распространенных команд, которые будут использоваться во всем этом скрипте, поэтому вы должны получить базовое представление о том, что это означает, прежде чем мы погрузимся в его собственно запись.
- ForEach-Object принимает массив или список объектов и выполняет указанную операцию для каждого из них. Внутри блока сценария ForEach-Object переменная $ _ используется для обращения к текущему обрабатываемому элементу.
- если еще операторы позволяют выполнять операцию только при выполнении определенных условий и (необязательно) указывать, что должно быть сделано, когда это условие не выполняется.
- переключатель заявления похожи на заявления с большим выбором. Коммутатор проверяет объект на несколько условий и запускает все блоки сценариев для условий, которые соответствуют объекту. Вы также можете указать блок по умолчанию, который будет запускаться только в том случае, если не будут сопоставлены никакие другие условия. Операторы switch также используют переменную $ _ для обращения к текущему обрабатываемому элементу.
- в то время как позволяет постоянно повторять блок сценария, пока выполняется определенное условие. Как только что-то происходит, что приводит к тому, что условие перестает быть истинным, когда блок сценария закончен, цикл завершается.
- попробуй поймать заявления помогают в обработке ошибок. Если что-то пойдет не так с блоком сценария, указанным для try, блок catch будет работать.
- Get-Content делает то, что говорит на олове.Он получает содержимое указанного объекта - обычно файл. Это можно использовать для отображения содержимого текстового файла на консоли или, как в этом скрипте, передать содержимое по конвейеру, которое будет использоваться с другими командами.
- Написать-Host помещает вещи в консоль. Это используется для представления сообщений пользователю и не входит в вывод сценария, если выход перенаправляется.
- Write-Output фактически генерирует выход. Обычно это сбрасывается на консоль, но также может быть перенаправлено другими командами.
В сценарии есть и другие команды, но мы объясним их, когда мы идем.
Создание сценария
Теперь пришло время заполучить руки.
Часть 1: Подготовка к работе
Если вам нравится, когда ваш скрипт запускается с чистой консоли, вот первая строка, в которой вы хотите.
Clear-Host
Теперь, когда у нас есть чистый экран, следующее, что мы хотим сделать, это проверить скрипт, чтобы убедиться, что все, что ему нужно, на месте. Для этого нам нужно начать с того, чтобы сказать, где искать и что искать.
$ScriptFolder = Split-Path $MyInvocation.MyCommand.Definition -Parent $RequiredFiles = ('Males.txt','Females.txt','Surnames.txt')
Первая строка очень полезна для любого скрипта. Он определяет переменную, указывающую на папку, содержащую скрипт. Это важно, если вашему сценарию нужны другие файлы, которые находятся в том же каталоге, что и он (или известный относительный путь из этого каталога), потому что в противном случае вы столкнетесь с ошибками, если и когда вы попытаетесь запустить скрипт, когда находитесь в другом рабочий каталог.
Во второй строке создается массив имен файлов, необходимых для правильного запуска скрипта. Мы будем использовать это вместе с переменной $ ScriptFolder в следующем фрагменте, где мы проверяем, будут ли эти файлы присутствовать.
$RequiredFiles | ForEach-Object { if (!(Test-Path '$ScriptFolder$_')) { Write-Host '$_ not found.' -ForegroundColor Red $MissingFiles++ } }
Этот кусок скрипта отправляет массив $ RequiredFiles в блок ForEach-Object. Внутри этого блока скрипта оператор if использует Test-Path, чтобы узнать, где именно он находится. Test-Path - это простая команда, которая при задании пути к файлу возвращает базовый истинный или ложный ответ, чтобы сообщить нам, указывает ли путь на то, что существует. Восклицательный знак есть не оператор, который отменяет ответ Test-Path перед передачей его в оператор if. Поэтому, если Test-Path возвращает false (то есть файл, который мы ищем, не существует), он будет преобразован в true, чтобы оператор if выполнил свой блок сценариев.
Другое замечание, которое будет часто использоваться в этом скрипте, заключается в использовании двойных кавычек вместо одиночных кавычек. Когда вы помещаете что-то в одинарные кавычки, PowerShell рассматривает его как статическую строку. Все, что есть в одинарных кавычках, будет передаваться точно как есть. Двойные кавычки подсказывают PowerShell переводить переменные и некоторые другие специальные элементы внутри строки, прежде чем передавать их. Здесь двойные кавычки означают, что вместо запуска Test-Path '$ ScriptFolder $ _' мы действительно будем делать что-то большее, как Test-Path 'C: Scripts Surnames.txt' (предполагая, что ваш скрипт находится в C: Scripts, а ForEach-Object в настоящее время работает над 'Surnames.txt').
Для каждого файла, не найденного, Write-Host отправит сообщение об ошибке в красный цвет, чтобы сообщить вам, какой файл отсутствует. Затем он увеличивает значение переменной $ MissingFiles, которая будет использоваться в следующей части, для ошибки и выхода, если бы отсутствовали файлы.
if ($MissingFiles) { Write-Host 'Could not find $MissingFiles source file(s). Aborting script.' -ForegroundColor Red Remove-Variable ScriptFolder,RequiredFiles,MissingFiles Exit }
Вот еще один аккуратный трюк, который вы можете сделать с операторами if. Большинство руководств, которые вы увидите о том, будут ли операторы подсказывать вам использовать оператор для проверки соответствия условия. Например, здесь мы могли бы использовать if ($ MissingFiles -gt 0) чтобы увидеть, больше ли $ MissingFiles больше нуля. Однако, если вы уже используете команды, которые возвращают логическое значение (как в предыдущем блоке, где мы использовали Test-Path), это необязательно. Вы также можете обойтись без него в таких случаях, когда вы просто проверяете, не отличается ли число от нуля. Любое ненулевое число (положительное или отрицательное) рассматривается как истинное, а нуль (или, как может случиться, здесь несуществующая переменная) будет считаться ложным.
Если $ MissingFiles существует и не равно нулю, Write-Host отправит сообщение, сообщающее вам, сколько файлов пропало и что сценарий будет прерван. Затем Remove-Variable очистит все переменные, которые мы создали, и Exit выйдет из сценария. На обычной консоли PowerShell Remove-Variable действительно не требуется для этой конкретной цели, потому что переменные, заданные сценариями, обычно отбрасываются при выходе сценария. Однако PowerShell ISE ведет себя по-другому, поэтому вы можете захотеть сохранить это, если вы планируете запустить скрипт оттуда.
Если все будет в порядке, сценарий будет продолжен. Еще одна подготовка к созданию - это псевдоним, который мы будем очень рады потом.
New-Alias g Get-Random
Псевдонимы используются для создания альтернативных имен команд. Они могут быть полезны, чтобы помочь нам познакомиться с новым интерфейсом (например: PowerShell имеет встроенные псевдонимы, такие как dir -> Get-ChildItem а также cat -> Get-Content) или сделать короткие ссылки для часто используемых команд. Здесь мы делаем очень короткая ссылка для Get-Random команда, которая будет использоваться позже.
Get-Random в значительной степени делает то, что подразумевает его название. Учитывая массив (например, список имен) в качестве входных данных, он выбирает случайный элемент из массива и выплевывает его. Он также может использоваться для генерации случайных чисел. То, что нужно помнить о Get-Random и числах, заключается в том, что, как и многие другие компьютерные операции, он начинает отсчет с нуля. Поэтому вместо Get-Random 10 что означает более естественное «дать мне число от 1 до 10», это действительно означает «дать мне число от 0 до 9.». Вы можете быть более конкретным относительно выбора номера, так что Get-Random ведет себя так же, как вы, естественно, ожидаем, но нам это не понадобится в этом скрипте.
Часть 2. Получение пользовательского ввода и получение работы
Хотя сценарий, который генерирует только одно случайное имя и номер телефона, велик, гораздо лучше, если скрипт позволяет пользователю указать, сколько имен и номеров они хотят получить в одной партии. К сожалению, мы не можем доверять пользователям всегда давать правильный ввод. Итак, это немного больше, чем просто $ UserInput = Read-Host.
while (!$ValidInput) { try { [int]$UserInput = Read-Host -Prompt 'Items to be generated' $ValidInput = $true } catch { Write-Host 'Invalid input. Enter a number only.' -ForegroundColor Red } }
Вышеприведенный оператор while проверяет и отрицает значение $ ValidInput. Пока $ ValidInput является ложным или не существует, он будет продолжать цикл через свой блок сценариев.
Оператор try принимает вход пользователя через Read-Host и пытается преобразовать его в целочисленное значение. (Это [INT] перед Read-Host.) Если он будет успешным, он установит значение $ ValidInput равным true, чтобы цикл while мог выйти. Если это не удалось, блок catch отправляет сообщение об ошибке и, поскольку параметр $ ValidInput не был установлен, цикл while возвращается и снова запрашивает пользователя.
После того, как пользователь правильно дал номер в качестве ввода, мы хотим, чтобы сценарий объявил, что он собирается начать фактически выполнять свою работу, а затем начать делать это.
Write-Host '`nGenerating $UserInput names & phone numbers. Please be patient.`n' 1..$UserInput | ForEach-Object { <# INSERT RANDOM NAME & NUMBER GENERATOR HERE #> }
Не волнуйтесь, мы не собираемся оставлять вас самостоятельно, чтобы выяснить случайный код имени и номера генератора. Это просто комментарий заполнителя, чтобы показать вам, где следующий раздел (где выполняется настоящая работа) подходит.
Строка Write-Host довольно проста. Он просто говорит, сколько имен и номеров телефонов будет генерировать сценарий, и просит пользователя проявить терпение, пока скрипт выполняет свою работу.`пв начале и в конце строки необходимо вставить пустую строку до и после этого вывода, чтобы дать ей некоторое визуальное разделение между строкой ввода и списком имен и чисел. Имейте в виду, что это обратный тик (AKA «серьезный акцент» - обычно ключевой выше вкладки, слева от 1), а не апостроф или одиночная кавычка перед каждым N.
В следующей части показан другой способ использования цикла ForEach-Object. Как правило, если вы хотите, чтобы блок сценариев запускался определенное количество раз, вы настраиваете регулярный цикл, например for ($ x = 1; $ x -le $ UserInput; $ x ++) {<# INSERT SCRIPT HERE #>}.ForEach-Object позволяет нам упростить это, подав ему список целых чисел, и вместо того, чтобы сообщать ему на самом деле делать что-либо с этими целыми числами, мы просто даем ему статический блок сценариев для запуска до тех пор, пока он не закончит целые числа.
Часть 3: Создание случайного имени
Генерация имени - это самый простой бит остальной части этого процесса. Он состоит только из трех шагов: выбор фамилии, выбор пола и выбор имени. Помните, что псевдоним, который мы сделали для Get-Random некоторое время назад? Пора начать использовать это.
$Surname = Get-Content '$ScriptFolderSurnames.txt' | g $Male = g 2 if ($Male) {$FirstName = Get-Content '$ScriptFolderMales.txt' | g} else {$FirstName = Get-Content '$ScriptFolderFemales.txt' | g}
Первая строка берет наш список фамилий, передает его в произвольный выборщик и присваивает выбранное имя $ Surname.
Вторая линия выбирает пол нашего человека. Помните, как Get-Random начинает отсчет с нуля, и как ноль ложный, а все остальное верно? Вот как мы используем Get-Random 2 (или намного короче г 2 благодаря нашему псевдониму - оба приводят к выбору между нулем или одним), чтобы решить, является ли наш человек мужчиной или нет. Оператор if / else впоследствии случайно выбирает имя мужчины или женщины соответственно.
Часть 4: Создание случайного номера телефона
Вот самая интересная часть. Ранее мы показали вам, как есть несколько способов сделать неверный или фиктивный номер телефона. Поскольку мы не хотим, чтобы все наши номера выглядели слишком похожими друг на друга, мы будем случайным образом выбирать недопустимый формат номера каждый раз. Случайно выбранные форматы будут определяться их кодом зоны и кодом Exchange, который будет храниться вместе как префикс $.
$NumberFormat = g 5 switch ($NumberFormat) { 0 {$Prefix = '($(g 2)$(g 10)$(g 10)) $(g 10)$(g 10)$(g 10)'} 1 {$Prefix = '($(g 10)9$(g 10)) $(g 10)$(g 10)$(g 10)'} 2 {$Prefix = '($(g 10)$(g 10)$(g 10)) $(g 2)$(g 10)$(g 10)'} 3 {$Prefix = '($(g 10)$(g 10)$(g 10)) $(g 10)11'} 4 {$Prefix = '($(g 10)$(g 10)$(g 10)) 555'} }
Первая строка - это простая генерация случайных чисел для выбора формата, который мы будем отслеживать по номеру телефона. Затем оператор switch принимает этот случайный выбор и соответственно генерирует префикс $. Помните этот список недопустимых типов номеров телефонов? Значения $ NumberFormat 0-3 соответствуют первым четырем в этом списке. Значение 4 может генерировать один из двух последних, поскольку оба используют код обмена «555».
Здесь вы также видите, что мы используем другой трюк с двойными кавычками. Двойные кавычки не просто позволяют интерпретировать переменные до того, как строка будет выводиться - они также позволяют обрабатывать блоки скриптов. Для этого вы завершите блок сценария следующим образом: "$ (<# SCRIPT HERE #>)", Таким образом, у вас выше много индивидуально рандомизированных цифр, причем некоторые из них либо ограничены в своем диапазоне, либо статически установлены в соответствии с правилами, которым мы должны следовать. Каждая строка также имеет круглые скобки и интервалы, как обычно вы ожидаете увидеть в кодовой строке и кодах кода Exchange.
Последнее, что нам нужно сделать, прежде чем мы готовы вывести наше имя и номер телефона, - это создать идентификатор подписчика, который будет храниться как $ Suffix.
switch ($NumberFormat) { {$_ -lt 4} {$Suffix = '$(g 10)$(g 10)$(g 10)$(g 10)'} 4 { switch ($Prefix) { '(800) 555' {$Suffix = '0199'} default {$Suffix = '01$(g 10)$(g 10)'} } } }
Из-за специальных правил для 555 номеров мы не можем просто генерировать четыре случайных цифры для конца каждого номера телефона, который будет создан нашим скриптом. Итак, первый коммутатор проверяет, имеем ли мы дело с номером 555. Если нет, он генерирует четыре случайных числа. Если это номер 555, второй коммутатор проверяет код зоны 800.Если это соответствует, существует только один действительный $ Suffix, который мы можем использовать. В противном случае ему разрешено выбирать что-либо между 0100-0199.
Обратите внимание, что есть несколько разных способов, которыми этот блок мог быть написан, а не так, как он есть. Оба оператора switch могли быть заменены операторами if / else, поскольку каждый из них обрабатывает только два варианта. Кроме того, вместо того, чтобы специально вызывать «4» в качестве опции для первого оператора switch, «default» можно было бы использовать аналогично тому, как это было сделано во втором, поскольку это был единственный вариант. Выбор между if / else vs. switch или тем, где использовать ключевое слово по умолчанию вместо конкретных значений, часто сводится к личным предпочтениям. Пока это работает, используйте то, с чем вам больше всего нравится.
Теперь пришло время выхода.
Write-Output '$FirstName $Surname $Prefix-$Suffix' }
Это почти так же просто, как и в скрипте. Он просто выводит имя и фамилию, разделенные пробелами, а затем пробел перед номером телефона. Здесь также добавляется стандартная тире между кодом Exchange и идентификатором подписчика.
Эта закрывающая скобка внизу является концом цикла ForEach-Object из более раннего периода - опустите это, если вы уже получили его.
Часть 5: Очистка и запуск скрипта
После того, как все сделано, хороший сценарий знает, как очистить после себя. Опять же, удаление переменной ниже на самом деле не требуется, если вы только собираетесь запускать скрипт с консоли, но вам это захочется, если вы когда-либо планируете запустить его в ISE.
Remove-Item alias:g Remove-Variable ScriptFolder,RequiredFiles,Surname,Male,FirstName,NumberFormat,Prefix,Suffix,ValidInput,UserInput
После того, как вы все это сделали, сохраните скрипт с расширением «.ps1» в той же папке, что и файлы имен. Убедитесь, что ваша ExecutionPolicy установлена так, чтобы скрипт мог запускаться и давать ему завихрение.
Вот скриншот сценария в действии:
Генератор случайных имен и телефонных номеров для PowerShell