10Sep

Hur man skapar slumpmässiga namn &Telefonnummer med PowerShell

När du behöver en dataset för testning eller demonstration, och den uppsättningen behöver representera personidentifierbar information( PII), vill du i allmänhet inte använda verkliga data som representerar verkliga personer. Här går vi igenom hur du kan använda PowerShell för att skapa en lista med slumpmässiga namn och telefonnummer för bara ett sådant tillfälle.

Vad du behöver

Innan du börjar, finns det några verktyg och information som du borde ha:

PowerShell

Detta skript har utvecklats med PowerShell 4.0 och har också testats för kompatibilitet med PowerShell 2.0.PowerShell 2.0 eller senare har inbyggts i Windows sedan Windows 7. Den är också tillgänglig för Windows XP och Vista som en del av Windows Management Framework( WMF).Några ytterligare detaljer, och länkar för nedladdningar, finns nedan.

  • PowerShell 2.0 levereras med Windows 7. Användare av Windows XP SP3 och Vista( SP1 eller senare) kan hämta den lämpliga WMF-versionen från Microsoft i KB968929.Det stöds inte på XP SP2 eller under eller Vista utan SP1.
  • PowerShell 4.0 levereras med Windows 8.1.Windows 7 SP1-användare kan uppgradera till den som en del av en WMF-uppdatering från Microsoft Download Center. Det är inte tillgängligt för XP eller Vista.

Namn

Du behöver några listor med namn för att mata in i slumpgeneratorn. En bra källa till -lot av namn och information om deras popularitet( även om det inte kommer att användas för det här skriptet) är United States Census Bureau. Listorna som finns tillgängliga på länkarna nedan är mycket stora, så du kanske vill trimma dem lite om du planerar att generera många namn och nummer samtidigt. På vårt testsystem tog varje namn / nummerpar cirka 1,5 sekunder för att generera med hjälp av fullständiga listor men din körsträcka varierar beroende på dina egna systemspecifikationer.

  • Efternamn
  • Manliga förnamn
  • Kvinna förnamn

Oavsett vilken källa du använder måste du skapa tre textfiler som manuset kan använda som pooler för namnvalet. Varje fil ska innehålla endast namn och endast ett namn per rad. Dessa måste lagras i samma mapp som ditt PowerShell-skript.

Efternamn.txt ska innehålla efternamnen som du vill att manuset ska välja från. Exempel:

Smith Johnson Williams Jones Brown

Males.txt ska innehålla de manliga förnamnen du vill att manuset ska välja från. Exempel:

James John Robert Michael William

Kvinnor.txt ska innehålla de kvinnliga förnamnen du vill att manuset ska välja från. Exempel:

Mary Patricia Linda Barbara Elizabeth

Regler för telefonnummer

Om du vill vara säker på att dina telefonnummer inte matchar någons riktiga telefonnummer är det enklaste sättet att använda den kända "555" Exchange Code. Men om du ska visa en dataset med många telefonnummer kommer den 555 att börja se ganska monotont riktigt snabbt. För att göra sakerna mer intressanta genererar vi andra telefonnummer som strider mot reglerna för nordamerikansk nummereringsplan( NANP).Nedan är några exempel ogiltiga telefonnummer som representerar varje klass av nummer som kommer att genereras av det här skriptet:

  • ( 157) 836-8167
    Detta nummer är ogiltigt eftersom Area Codes inte kan börja med en 1 eller 0.
  • ( 298) 731-6185
    Detta nummer är ogiltigt eftersom NANP inte tilldelar riktnummer med 9 som den andra siffran.
  • ( 678) 035-7598
    Detta nummer är ogiltigt eftersom Exchange-koderna inte kan börja med en 1 eller 0.
  • ( 752) 811-1375
    Detta nummer är ogiltigt eftersom Exchange-koderna inte kan slutas med två 1s.
  • ( 265) 555-0128
    Detta nummer är ogiltigt eftersom Exchange-koden är 555, och är abonnent-ID inom det område som är reserverat för fiktiva nummer.
  • ( 800) 555-0199
    Detta nummer är det enda 800-numret med en 555 Exchange-kod som är reserverad för användning som ett fiktivt nummer.

Observera att ovanstående regler kan ändras och kan variera beroende på behörighet. Du borde göra din egen forskning för att verifiera de nuvarande reglerna som är tillämpliga på den ort där du kommer att generera telefonnummer.

gemensamma kommandon

Det finns några ganska vanliga kommandon som ska användas i hela det här skriptet, så du borde få en grundläggande uppfattning om vad dessa betyder innan vi dyker in i att faktiskt skriva det.

  • ForEach-Object tar en matris eller lista över objekt och utför den angivna funktionen på var och en av dem. Inom ett script för ForEach-Object-skript används variabeln $ _ för att referera till det aktuella objektet som behandlas.
  • om. .. annat uttalanden tillåter dig att utföra en operation endast om vissa villkor är uppfyllda och( valfritt) ange vad som ska göras när det här villkoret inte är uppfyllt.
  • switch uttalanden är som om uttalanden med fler val. Omkopplaren kontrollerar ett objekt mot flera villkor och kör vilka scriptblock som anges för förhållanden som objektet matchar. Du kan också, valfritt, ange ett standardblock som bara körs om inga andra villkor matchas. Omkopplingsdeklarationer använder också variabeln $ _ för att referera till det aktuella objektet som behandlas.
  • medan -satser tillåter dig att kontinuerligt upprepa ett manuskript så länge som ett visst villkor är uppfyllt. När något händer som gör att tillståndet inte längre är sant när manusblocket är klart, kommer slingan att gå ut.
  • försök. .. fånga -satser med hjälp av felhantering. Om något går fel med det manusblock som anges för försök, kommer fångstblocket att springa.
  • Get-Content gör vad det står på tennet. Det blir innehållet i ett visst objekt - vanligtvis en fil. Detta kan användas för att visa innehållet i en textfil på konsolen eller, som i det här skriptet, skicka innehållet längs rörledningen som ska användas med andra kommandon.
  • Write-Host sätter saker i konsolen. Detta används för att presentera meddelanden till användaren och ingår inte i skriptets utdata om utmatningen omdirigeras.
  • Skrivutgång genererar faktiskt utdata. Normalt dumpas detta till konsolen, men det kan också omdirigeras av andra kommandon.

Det finns andra kommandon i manuset, men vi kommer att förklara dem när vi går.

Bygga skriptet

Nu är det dags att få våra händer smutsiga.

Del 1: Att bli redo att gå

Om du gillar att ditt skript börjar starta från en ren konsol, här är den första raden du vill ha i den.

Clear-Host

Nu när vi har en ren skärm, är nästa sak vi vill göra, att skriptet kontrollerar att allt som behövs är på plats. För att göra det måste vi börja med att berätta var du ska leta och vad du ska leta efter.

$ ScriptFolder = Split-Path $ MyInvocation. MyCommand. Definition -Parent $ RequiredFiles =( 'Males.txt', 'Females.txt', 'Surnames.txt')

Den första raden där är mycket användbar för något manus. Det definierar en variabel som pekar på mappen som innehåller manuset. Detta är viktigt om ditt skript behöver andra filer som finns i samma katalog som sig själv( eller en känd relativ sökväg från den katalogen), eftersom du annars kommer att stöta på fel om och när du försöker köra skriptet medan du befinner dig i en annanarbetsregister.

Den andra raden skapar en rad filnamn som krävs för att skriptet ska köras korrekt. Vi använder detta tillsammans med $ ScriptFolder-variabeln i nästa stycke där vi kontrollerar att filerna är närvarande.

$ RequiredFiles |ForEach-Object{ if( !( Test-Path "$ ScriptFolder \ $ _")){ Skriv-värd "$ _ hittades inte."-ForegroundColor Red $ MissingFiles ++}}

Denna bit av script skickar arrayen RequiredFiles till ett ForEach-Object-block. Inom det här scriptblocket använder testet Om test-sökvägen för att se om filen vi letar efter är var den hör hemma. Test-Path är ett enkelt kommando som, när den ges en filväg, returnerar ett grundläggande sant eller falskt svar för att berätta om sökvägen pekar på något som finns. Utropstecken där finns en , inte -operatör, som reverserar svaret på Test-Path innan det vidarebefordras till if-uttalandet. Så om Test-Path returnerar false( det vill säga filen vi letar efter existerar inte) kommer den att konverteras till sant så att if-satsen kommer att exekvera dess skriptblock.

En annan sak att notera här, som ofta används i det här skriptet, är användningen av dubbla citat istället för enkla citat. När du lägger något i enkla citat behandlar PowerShell det som en statisk sträng. Vad som helst i de enkla citat kommer att skickas längs exakt som-är. Dubbla citat berättar PowerShell att översätta variablerna och några andra speciella objekt inom strängen innan de passerar den. Här betyder dubbla citat att i stället för att köra Test-Path '$ ScriptFolder \ $ _' gör vi faktiskt något mer som Test-Path 'C: \ Scripts \ Surnames.txt' ( förutsatt att dinSkriptet finns i C: \ Skript och ForEach-Object arbetar för närvarande med "Surnames.txt").

För varje fil som inte hittas, skriver Write-Host ett felmeddelande i rött för att berätta vilken fil som saknas. Då ökar det $ MissingFiles-variabeln som kommer att användas i nästa bit, för att fel och sluta om det fanns några filer som saknas.

om( $ MissingFiles){ Write-Host "kunde inte hitta $ MissingFiles källfil( er). Avbrytande script."-ForegroundColor Red Remove-Variable ScriptFolder, RequiredFiles, MissingFiles Exit}

Här är ett annat snyggt trick du kan göra med om uttalanden. De flesta guider du ser om uttalanden kommer att berätta för dig att använda en operatör för att kontrollera om ett matchande villkor. Till exempel kan vi använda om( $ MissingFiles -gt 0) för att se om $ MissingFiles är större än noll. Men om du redan använder kommandon som returnerar ett booleskt värde( som i det föregående blocket där vi använde testvägen) är det inte nödvändigt. Du kan också göra det utan i fall som här, när du bara testar för att se om ett tal är noll. Eventuella icke-nollnummer( positiva eller negativa) blir behandlade som sanna, medan noll( eller, som det kan hända här, en obefintlig variabel) behandlas som falskt.

Om $ MissingFiles existerar, och är icke-noll, skickar Write-Host ett meddelande som berättar hur många filer som saknades och att manuset avbryts. Då tar Remove-Variable bort alla variabler som vi har skapat och Exit kommer att sluta skriptet. Vid den vanliga PowerShell-konsolen behövs inte Ta bort-Variabel för detta ändamål, eftersom variabler som ställs in av skript normalt kasseras när man skriver ut. PowerShell ISE beter sig dock lite annorlunda, så du kanske vill behålla detta om du planerar att köra manuset därifrån.

Om alla saker är i ordning fortsätter skriptet. En ytterligare förberedelse att göra är ett alias som vi kommer att vara väldigt glada över senare.

Ny alias g Slumpmässig

Aliaser används för att skapa alternativa namn för kommandon. Dessa kan vara användbara för att hjälpa oss att lära känna det nya gränssnittet( t.ex.: PowerShell har inbyggda aliaser som dir - & gt; Get-ChildItem och katt -> Get-Content ) eller för att göra korta referenserför vanliga kommandon. Här gör vi en mycket kort referens för Random kommandot som kommer att användas mycket senare.

Slumpmässig gör ganska mycket vad namnet antyder. Med en matris( som en lista med namn) som input väljer den ett slumpmässigt objekt från matrisen och spetsar ut det. Det kan också användas för att generera slumptal. Saken att komma ihåg om Get-Random och siffror är dock att det, liksom många andra datoperationer, börjar det räknas från noll. Så istället för Random 10 , vilket betyder att det är mer naturligt "ge mig ett tal från 1 till 10" betyder det verkligen "ge mig ett tal från 0 till 9." Du kan vara mer specifik om antalet val, så att Get-Random beter sig mer som du naturligtvis förväntar dig, men vi behöver inte det i det här skriptet.

Del 2: Få användarinmatning och komma igång

Medan ett skript som genererar bara ett slumpmässigt namn &telefonnummer är bra, det är mycket bättre om manuset tillåter användaren att ange hur många namn &nummer de vill få i en sats. Tyvärr kan vi inte verkligen lita på att användarna alltid ger giltig inmatning. Så det finns en liten bit mer till detta än bara $ UserInput = Read-Host .

medan( ! $ ValidInput){ försök{ [int] $ UserInput = Read-Host -Prompt 'Produkter som ska genereras' $ ValidInput = $ true} fånga{ Write-Host 'Ogiltig inmatning. Ange bara ett nummer. '-ForegroundColor Red}}

Medans uttalande ovan kontrollerar och negerar värdet på $ ValidInput. Så länge som $ ValidInput är felaktigt, eller inte existerar, fortsätter det att loopa genom sitt manuskript.

Försökets uttalande tar användarinmatning via Read-Host och försöker konvertera det till ett heltal.(Det är [int] före Read-Host.) Om det lyckas kommer det att ställa in $ ValidInput till true så att while loop kan avslutas. Om det inte lyckas, lägger fångstblocket ett fel och eftersom $ ValidInput inte blev inställd, kommer slingan återvända och uppmanar användaren igen.

När användaren korrekt har angivit ett tal som inmatning, vill vi att manuset ska meddela att det är på väg att börja faktiskt göra sitt arbete och sedan skaffa sig det.

Skriv-värd "` nGenerering $ UserInput namn och telefonnummer. Var vänlig patient.`n "1. . $ UserInput |ForEach-Object{ & lt; # INSERT RANDOM NAME &NUMBER GENERATOR HERE # & gt;}

Oroa dig inte, vi kommer inte att lämna dig själv för att ta reda på slumpmässigt namn &Nummergenerator kod. Det är bara en platshållare kommentar för att visa dig var nästa avsnitt( där det verkliga jobbet blir gjort) kommer att passa.

Skriv-Host-linjen är ganska enkel. Det säger helt enkelt hur många namn och telefonnummer skriptet ska generera, och frågar användaren att vara tålmodig medan manuset gör sitt arbete. `n i början och slutet av strängen är att infoga en tom linje före och efter den utsignalen, bara för att ge den viss visuell åtskillnad mellan ingångsledningen och listan över namn &tal. Var medveten om att det är en back-tick( AKA "Grave Accent" - vanligtvis knappen ovanför fliken, till vänster om 1) och inte en apostrof eller ett citat framför varje n .

Nästa del visar ett annat sätt att du kan använda en ForEach-Object-loop. När du vill att ett manusblock ska köra ett visst antal gånger, ställer du vanligtvis en regelbunden till loop som för( $ x = 1; $ x -le $ UserInput; $ x ++){ & lt; # INSERT SCRIPTHÄR & gt;}. ForEach-Object låter oss förenkla detta genom att mata det en lista med heltal och istället för att säga att det faktiskt gör någonting med dessa heltal ger vi bara ett statiskt manuskriptblock för att köra tills det går tom för heltal för att göra det för.

Del 3: Generera ett slumpmässigt namn

Att generera namnet är den enklaste delen av resten av processen. Den består bara av tre steg: Plocka ett efternamn, välja ett kön och välja ett förnamn. Kommer du ihåg att alias vi gjort för ett slumpmässigt tag tillbaka? Det är dags att börja använda det.

$ Efternamn = Hämta innehåll "$ ScriptFolder \ Surnames.txt" |g $ Man = g 2 om( $ Man){ $ FirstName = Get-Content "$ ScriptFolder \ Males.txt" |g} else{ $ FirstName = Get-Content "$ ScriptFolder \ Kvinnor.txt" |g}

Den första raden tar vår förteckning över efternamn, matar in den i slumpmässig väljare och tilldelar det valda namnet till $ efternamn.

Den andra raden väljer vår persons kön. Kom ihåg hur Get-Random börjar räkna från noll, och hur noll är falskt och allt annat är sant? Så använder vi Random 2 ( eller den mycket kortare g 2 tack vare vårt alias - båda resulterar i val mellan noll eller en) för att bestämma om vår person är man eller inte. Om / else-uttalandet väljer därefter slumpmässigt ett man- eller honförnamn i enlighet med detta.

Del 4: Generera ett slumpmässigt telefonnummer

Här är den riktigt roliga delen. Tidigare visade vi dig hur det finns flera sätt att göra ett ogiltigt eller fiktivt telefonnummer. Eftersom vi inte vill att alla våra siffror ser ut som liknar varandra, väljer vi slumpmässigt ett ogiltigt nummerformat varje gång. De slumpmässigt valda formaten definieras av deras area code och Exchange Code, som gemensamt lagras som $ Prefix.

$ NumberFormat = g 5 switch( $ NumberFormat){ 0{ $ Prefix = "($( g 2) $( g 10) $( g 10)) $( g 10) $( g 10) $( g 10)"{$ Prefix ="( $( g 10) 9 $( g 10)) $( g 10) $( g 10) $( g 10) "} 2{ $ Prefix ="( $( 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 "}}

Den första raden är en enkel slumptalgeneration för att välja vilket formatvi kommer att följa för telefonnumret. Då tar brytningsdeklarationen det slumpmässiga valet och genererar ett $ prefix i enlighet därmed. Kom ihåg att listan med ogiltiga telefonnummertyper?$ NumberFormat-värdena 0-3 motsvarar de första fyra i den listan. Värde 4 kan generera ett av de två sista, eftersom båda använder "555" Exchange Code.

Här kan du också se att vi använder ett annat trick med dubbla citat. Dubbla citat låter dig inte bara tolka variabler innan en sträng får output - de låter dig också bearbeta manusblock. För att göra det sätter du in skriptblocket så här: "$( & lt; #SCRIPT HERE # & gt;)" .Så vad du har ovan är en hel del individuellt randomiserade siffror, med några av dem antingen begränsade i sitt sortiment eller statiskt inställda enligt de regler som vi behöver följa. Varje sträng har också parentes och avstånd som du normalt förväntar dig att se i ett riktnummer och Exchange Code-par.

Det sista vi behöver göra innan vi är redo att skriva ut vårt namn &telefonnummer är att skapa ett abonnent-ID, som kommer att sparas som $ suffix.

-omkopplare( $ NumberFormat){ {$ _ -lt 4}{ $ Suffix = "$( g 10) $( g 10) $( g 10) $( g 10)"} 4{ switch( $ Prefix){ '(800) 555 '{$ Suffix =' 0199 '} standard{ $ Suffix = "01 $( g 10) $( g 10)"}}}}

På grund av de speciella reglerna för 555 nummer kan vi inte baragenerera fyra slumpmässiga siffror för slutet av varje telefonnummer som vårt skript kommer att göra. Så, den första omkopplaren kontrollerar för att se om vi hanterar ett 555-nummer. Om inte, genererar det fyra slumpmässiga siffror. Om det är ett 555-nummer, kontrollerar den andra omkopplaren för 800-områdeskoden. Om det matchar, finns det bara en giltig $ Suffix som vi kan använda. Annars är det tillåtet att välja mellan allt mellan 0100-0199.

Observera att det finns några olika sätt att det här blocket kunde ha skrivits, istället för hur det är. Båda omkopplingsdeklarationerna kunde ha ersatts med if / else uttalanden, eftersom de var och en endast hanterar två val. I stället för att specifikt kalla ut "4" som ett alternativ för den första omkopplingsdeklarationen, kunde "standard" ha använts på samma sätt som det var gjort i det andra eftersom det var det enda alternativet kvar. Valet mellan if / else vs switch, eller var du ska använda standardsökordet istället för specifika värden, kommer ofta till en fråga om personlig preferens. Så länge det fungerar, använd vad du är mest bekväm med.

Nu är det dags för produktion.

Write-Output "$ Förnamn $ Efternamn $ Prefix- $ Suffix"}

Det här är ganska enkelt så som det blir i manuset. Det matar ut först och efternamn separerat av mellanslag, sedan ett annat utrymme före telefonnumret. Här får du också standardfliken mellan Exchange Code och Subscriber ID.

Den stängningsfästet längst ner är slutet på ForEach-Object-loopen från tidigare - släpp om det här om du redan har det.

Del 5: Rengöring och körning av manuskriptet

Efter allt arbete är gjort, vet ett bra skript hur man rensar efter sig själv.Återigen behövs inte den rörliga borttagningen nedan om du bara ska köra skriptet från konsolen, men du vill ha det om du någonsin planerar att köra den i ISE.

Remove-Item-alias: \ g Remove-Variable ScriptFolder, RequiredFiles, Efternamn, Man, Förnamn, NumberFormat, Prefix, Suffix, ValidInput, UserInput

När du har gjort allt, spara manuset med en ".ps1" -tilläggi samma mapp som dina namnfiler. Se till att din ExecutionPolicy är inställd så att skriptet kan köras och ge det en virvel.

Här är en skärmdump av manuset i aktion:

Du kan också ladda ner en ZIP-fil som innehåller detta PowerShell-skript och textfiler med namnlistor, från länken nedan.

Slumpmässigt namn &Telefonnummer Generator för PowerShell