Visa information om framgången med powershell-kommandot. Hur man skapar kommandon och funktioner i Powershell anropa dem och skicka parametrar


PowerShellär en objektorienterad programvarumotor och ett skriptspråk med ett kommandoradsgränssnitt som ger IT-proffs fler alternativ för att konfigurera operativsystem i MS Windows-familjen. Enkelt uttryckt är det ett slags universellt administrationsverktyg. Den här artikeln kommer att täcka de grundläggande teknikerna för att skriva skript i PowerShell, som låter dig automatisera hanteringen av din Windows-miljö på ett enkelt sätt.

PowerShell erbjuder både ett rent konsolgränssnitt och en komplett utvecklingsmiljö. PowerShellISE(Integrerad skriptmiljö, inbyggd skriptmiljö) för skript. För att starta kommandoradsgränssnittet, skriv powershell i Kör-menyn (WinKey + R). PowerShell ISE startas med kommandot "PowerShell ISE" på samma meny.

ISE är att föredra eftersom det ger fler utvecklaralternativ med syntaxmarkering, autokompletterande kod och andra funktioner som finns i många "stora" IDE:er.

Att skriva och köra skript

Skript sparas som filer med filtillägget .ps1. Även om PowerShell har varit en inbyggd del av Windows under lång tid, kommer du inte att kunna köra dess skript med ett enkelt dubbelklick. För att göra detta, högerklicka på skriptet och välj "Kör i PowerShell".

Det finns också systempolicyer som begränsar exekveringen av skript. Du kan kontrollera de aktuella policyinställningarna genom att utfärda kommandot Get-ExecutionPolicy. Resultatet blir ett av följande värden:

  • Begränsad- Utförande av skript är förbjudet. Standardkonfiguration;
  • Allsignerad- du kan köra skript signerade av en pålitlig utvecklare; PowerShell kommer att be dig om bekräftelse innan du kör skriptet;
  • Fjärrsignerad- du kan köra dina egna skript eller de som är signerade av en pålitlig utvecklare;
  • Obegränsad- du kan köra alla skript.

För att komma igång måste du ändra startpolicyinställningen till RemoteSigned med kommandot Set-ExecutionPolicy:

Cmdlets

Cmdlets är kommandon med en fördefinierad funktion, liknande villkorliga uttalanden i programmeringsspråk. De har flera nyckelfunktioner:

  • det finns system-, användar- och valfria cmdlets;
  • resultatet av exekveringen av cmdlet kommer att vara ett objekt eller en array av objekt;
  • cmdlets kan bearbeta data och skicka dem till andra cmdlets med hjälp av pipelines;
  • cmdlets är skiftlägesokänsliga, så det finns ingen skillnad mellan Get-ADUser , get-aduser och get-AdUsEr ;
  • ett tecken används som avgränsare; .

Varje cmdlet innehåller ett verb och ett substantiv separerade med ett bindestreck. Till exempel:

  • GetProcess- visa de aktuella processerna som körs på datorn;
  • Få service- visa en lista över tjänster och deras status;
  • Få innehåll- visa innehållet i den angivna filen, till exempel Get-Content C:\Windows\System32\drivers\etc\hosts .

Om det behövs kan en lista över alla tillgängliga cmdlets visas med hjälp av Get-Help-Category:

Du kan också skapa dina egna cmdlets.

Parametrar

Varje cmdlet har flera parametrar som avgör hur den fungerar. PowerShell ISE föreslår automatiskt alla tillgängliga alternativ och visar deras typ. Till exempel, Get-Service-NameW* listar tjänster vars namn börjar med W . Om du har glömt vilka parametrar den angivna cmdleten har, använd Get-Member . Till exempel, Get-Process | GetMember:

Om du inte hittar det du letar efter, eller om du inte är säker på hur parametrarna är korrekt inställda, kan du till och med begära exempel med parametern -Examples:

Vissa cmdlets kan också anropas med hjälp av alias, till exempel, istället för Get-Help kan du helt enkelt skriva Hjälp .

När du skriver stora manus eller samarbetsutveckling kan du använda kommentarer. Varje kommentar börjar med ett # tecken, och ett block av kommentarer är begränsat till kombinationer av tecken<# и #>i början respektive slutet.

Transportband

PowerShell låter dig utbyta data mellan cmdlets med hjälp av en pipeline. Till exempel:

  • GetService | SortObject -property Status - sortering av pågående tjänster efter status;
  • Hej världen! | Out-File C:\ps\test.txt - skriv text till en fil.

Du kan använda flera pipelines. Till exempel listar följande skript namnen på alla tjänster utom de som är stoppade:

Få service | WHERE ($_.status -eq "Kör") | VÄLJ visningsnamn

Slutsats

Så tack vare den här guiden har nybörjare en uppfattning om vad PowerShell är. Vi tittade också på alternativ för att ändra skriptkörningspolicyn, vad en cmdlet är, hur de kommunicerar med hjälp av en pipeline och hur man får fram egenskaperna för det önskade objektet. Kom ihåg att vid svårigheter kan du använda Get-Help-cmdleten.

Den här artikeln är en textversion av en lektion från vår gratis PowerShell och Active Directory Basics videokurs (använd det hemliga ordet "blogg" för fullständig åtkomst).

Den här videokursen har visat sig vara väldigt populär över hela världen och kommer att leda dig genom stegen för att bygga en komplett uppsättning Active Directory-hanteringsverktyg från grunden.

Kodning med PowerShell

Till en början kan det verka som en svår uppgift att komma igång med PowerShell, särskilt om du under åren har vant dig vid att arbeta med kommandoraden cmd.exe och de så kallade "bat-filerna" (filer med tilläggen .bat och .cmd). I den här artikeln, baserat på materialet från den andra lektionen i vår videokurs, kommer vi att berätta hur och varför du bör uppgradera dina PowerShell-färdigheter, samt analysera grunderna för att starta PowerShell-redigeraren, lära dig automatiskt slutförande av kommandon, och hur man får aktuell information i en svår situation, hjälp och exempel.

Utför kommandon

PowerShell-konsolen är en interaktiv miljö som låter dig köra olika kommandon i realtid. Här behöver du inte först redigera skriptet i notepad och först sedan köra det på kommandoraden, vilket också kommer att spara mycket tid.

Om du för närvarande arbetar i en organisation som existerar i mer än en dag, har du förmodligen redan flera små skript för varje dag som du kör från kommandoraden cmd.exe. Och det här är fantastiska nyheter! Så du kan lika gärna göra allt detta från PowerShell. Detta var ett riktigt klokt designbeslut från Microsofts sida, eftersom de gjorde det lättare för administratörer att migrera till den nya lösningen.

Till utseendet ser PowerShell-redigeraren ut och fungerar exakt som kommandoradsmiljön cmd.exe. De knep och färdigheter du redan känner till kommer att fungera på samma sätt i PowerShell. Och om du också vill förbättra ditt spel och arbetar på att gå bort från att utföra engångsuppgifter till att tillhandahålla mer automatiserad administration, är det ett bra ställe att börja använda PowerShell i stället för kommandoraden.

Alla dina ofta använda verktyg som ping, ipconfig, nslookup, etc. kommer att fungera precis som du förväntar dig.

Hur man hittar PowerShell-kommandon

Folk älskar PowerShell för att det är så, ja, kraftfullt! Men den kraften kommer från en helt galen mängd inbyggda funktioner. Det är helt enkelt inte möjligt, och förmodligen inte praktiskt, för någon att memorera alla möjliga kommandon, cmdlets, flaggor, filter och andra sätt att berätta för PowerShell vad man ska göra och hur.

Lyckligtvis finns det flera verktyg inbyggda direkt i redigeraren för att hjälpa dig att hantera detta.

Automatisk komplettering av kommandon när du trycker på Tab

Det finns inget behov av att memorera de olika kommandona eller den exakta stavningen av kommandot. Ringa

Get-c
Nu genom att trycka på Tab-tangenten kan du bläddra igenom alla tillgängliga kommandon som börjar med de tecken som du redan har angett. Och detta fungerar i vilken del som helst av kommandot du försöker referera till: i kommandonamn och flaggor, och även när du autokompletterar fullständiga sökvägar i filsystemet.

Hämta-kommando

Även om flikkomplettering fungerar utmärkt, vad händer om du inte vet det korrekta namnet på kommandot du behöver? I det här fallet kan du använda kommandot för att hitta andra tillgängliga kommandon: Get-Command.

När du letar efter kommandonamn är det viktigt att komma ihåg att det finns en syntax för dem: Verb-substantiv. Som regel är verb som - Hämta (Hämta), Ställ in (Installera), Lägg till (Lägg till), Rensa (Rensa), Läs (Läs) och Skriv (Skriv) och Substantiv - filer, servrar eller andra enheter i ditt nätverk och applikationer.

GetCommandär ett verktyg för att hitta och lära sig de kommandon som finns på din dator.

Kommandosyntax i PowerShell

Någon beskrev en gång Perl-skriptspråket som "körbart linjebrus" - ett otroligt användbart verktyg, med en väldigt ogenomskinlig syntax och en motsvarande hög ingångströskel för att lära sig det.

Även om du räknar ut det, är den traditionella kommandoraden i Windows inte så långt borta från detta. Tänk på den allmänna uppgiften att hitta alla filer i en katalog vars namn börjar med 'foo'.

CMD: FÖR /D /R %G IN (“Foo*”) GÖR @ECHO %G
FOR och DO indikerar att detta är en loop.
/D-flaggan indikerar att detta är en loop genom alla mappar
/R-flaggan anger att alla filer och mappar ska inkluderas, inklusive underkataloger
Sökmönstret som definierar uppsättningen filer vi är intresserade av betecknas med "IN"
ECHO indikerar att skriptet ska visa resultatet av varje slinga och slutligen
%G är en "obligatorisk parameter" och väljs för att tidigare Microsoft-programmerare redan har använt bokstäverna A, D, F, N, P, S, T och X när de utvecklar. Därför är det bra att börja med G, för att. detta ger dig den största uppsättningen oanvända bokstäver för returnerade variabla sökvägsformat (G, H, I, J, K, L, M) - med andra ord, det är ett hack.

Jämför nu PowerShell-motsvarigheten:

PowerShell: Get-ChildItem -Path C:\ -Filter 'Foo*'
Resultatet är detsamma, men även med ett sådant ganska trivialt exempel blir det mycket lättare att förstå vad som händer. Det blir direkt uppenbart vad varje element i kommandot gör och hur du kan ändra dem. Jo, förutom jokertecknet '*' som används i båda exemplen, men jag tror att du redan vet mycket väl vad det betyder - att alla element måste börja med 'Foo' och något annat i slutet.

Känner du hur ditt humör gradvis förbättras? Nu, vad händer om du vill veta hur man bara väljer filer (och inte mappar) i en sökväg? Kan du gräva i manualerna, eller kan din bästa vän Google hjälpa dig, eller kanske försöka ta reda på det från kommandoraden? Ett litet tips: om du är i PowerShell, skriv "-" och tryck på Tab-tangenten, bläddra igenom lämpliga flaggor tills den uppenbara lösningen visas.

En lång sträng vs objekt

Ingen behöver hemsidor om de inte är online. Det är därför folk spenderar enormt mycket tid på att låtsas vara ekolodsoperatörer på en ubåt och "pinga" tillgängligheten för deras servrar (ja, det är därför det kallas så).

Även om utdata från Ping-kommandot är till hjälp (och du kan pinga lika bra i PowerShell-konsolen), är det i slutändan bara en stor, lång sträng - en serie bokstäver och siffror med några pauser emellan.

PowerShell har ett kommando som liknar Ping, men returnerar data på ett strukturerat sätt. Detta är kommandot Test-Connection.

Här är resultatet av att köra det här kommandot för att utbyta paket med 'DC'-servern i en helt annan, fullt strukturerad form:

För att inte tala om att det är mycket lättare att läsa, men huvudsaken är att du nu kan skicka denna information till inmatningen av ett annat kommando, göra den ännu mer användbar (vår fullständiga videokurs är designad för detta), eller helt enkelt anpassa den så att det blev mer vettigt.

Inbyggd hjälp

Fram till denna punkt har vi fokuserat på att utföra vissa kommandon med Tab Padding, men när du väl börjar arbeta med PowerShell blir fler och fler kommandon mer komplexa med ännu mer komplexa alternativ. Medan verb-substantiv-syntaxen hjälper, hjälper det ännu mer att ha till hands:

1. Uppdaterad dokumentation
2. Överflöd av exempel

Hjälp med cmdlets

I praktiken bör du kombinera Get-Command (för att hitta vad du ska använda) och sedan använda Get-Help för att ta reda på hur du använder just det kommandot.

Ett praktiskt exempel på hur du gör detta: låt oss säga att du måste bestämma alla Windows-tjänster som körs på en dator.

För att komma igång kan du leta efter kommandon för att interagera med tjänster:

Get-Command-tjänst
Vilket låter dig veta direkt att du är på rätt väg. När du överväger att återgå till standardsyntaxen för PowerShell Verb-Noun-kommando, vill du ta reda på hur du korrekt använder kommandot 'Get-Service'.

Microsoft-dokumentation om kommandot Get-Service
För att göra detta, använd kommandot 'Get-Help'. Börja skriva
"Få hjälp -" och tryck sedan på tabbtangenten
Du kommer snabbt att upptäcka de tillgängliga alternativen, det mest uppenbara är "Namn", så det är värt ett försök:

Get-Help -Name Get-Service
Här får du hela syntaxen för kommandot (och vilka alternativ du kan inkludera eller utesluta baserat på filter).

Om du vill utforska kommandot mer på djupet och detaljera det ner till varje parameter, skriv sedan:

Get-Help -Name Get-Service - Parameternamn

Hjälp med PowerShell-exempel

Vi är alla människor och, ingen anstöt Google-bot, vi har alla våra egna psykologiska hinder som vi måste övervinna när vi lär oss något obekant och föra det till en form som vi kan förstå för att åstadkomma det vi behöver.

Genom att ange "-exempel" eller genom att lägga till "-detail"-flaggan till kommandot "Get-Help" kommer du att få en uppsättning exempel för användning av kommandot.
Till exempel, här är utdata för kommandot:

Get-Help -Name Get-Service -Exempel

Håller sig uppdaterad

Vad kan vara värre än ett trasigt exempel, eller ett exempel med fel i dokumentationen. Ofta beror detta antingen på föråldrad dokumentation, felaktiga exempel eller uppdaterade bibliotek.

För att kringgå dessa problem och få nya exempel och korrigeringar samtidigt, skriv:

uppdatera-hjälp
och processen att ladda ner den uppdaterade kontextuella hjälpen börjar.

Du kan hjälpa till och överföra en del medel för utvecklingen av webbplatsen

När vi arbetar i PowerShell-skalet har vi ännu inte tänkt på hur systemet genererar textrader som visas som ett resultat av att köra ett visst kommando (kom ihåg att PowerShell-cmdlets returnerar .NET-objekt, som i regel inte vet hur visas på skärmen).

Faktum är att PowerShell har en databas (uppsättning XML-filer) som innehåller standardformaterare för olika typer av .NET-objekt. Dessa moduler bestämmer vilka egenskaper för ett objekt som visas i utdata och i vilket format: en lista eller en tabell. När ett objekt når slutet av pipelinen bestämmer PowerShell dess typ och letar efter det i listan över objekt för vilka en formatregel är definierad. Om den här typen finns i listan, tillämpas motsvarande formatterare på objektet; Om inte, visar PowerShell helt enkelt egenskaperna för det .NET-objektet.

Också i PowerShell kan du uttryckligen ställa in reglerna för formatering av data som matas ut av cmdlets, och som kommandotolken Cmd.exe, omdirigera dessa data till en fil, skrivare eller tom enhet.

Formatera utdatainformation

I traditionella skal formaterar kommandon och verktyg själva utmatningen. Vissa kommandon (till exempel dir i Cmd.exe-tolken) låter dig anpassa utdataformatet med speciella alternativ.

I PowerShell formaterar endast fyra specialformat cmdlets (tabell 17-3). Detta gör inlärningen enklare eftersom du inte behöver komma ihåg formateringsverktygen och alternativen för andra kommandon (resten av cmdletarna formaterar inte utdata).

Tabell 17.3. Utdataformatering PowerShell-cmdlets
Cmdlet Beskrivning
Formatera tabell Formaterar kommandoutgången som en tabell vars kolumner innehåller objektegenskaper (beräknade kolumner kan också läggas till). Möjligheten att gruppera utdata stöds
Formatlista Utdata formateras som en lista med egenskaper, där varje egenskap visas på en ny rad. Möjligheten att gruppera utdata stöds
format-anpassad För att formatera utdata används en anpassad vy (vy)
format brett Formaterar objekt som en bred tabell som endast visar en egenskap för varje objekt

Som nämnts ovan, om ingen av format-cmdletarna är explicit specificerad, används standardformateraren, vilket bestäms av typen av data som visas. Till exempel, när du kör Get-Service cmdlet, visas data som standard som en tabell med tre kolumner (Status, Namn och Visningsnamn):

PS C:\> Get-Service Status Namn DisplayName ------ ---- ----------- Stoppad Alerter Alerter Kör ALG Application Level Gateway Service Stoppad AppMgmt Application Control Stoppad aspnet_state ASP.NET State Service Kör Ati HotKey Poller Ati HotKey Poller Kör AudioSrv Windows Audio Kör BITS Bakgrund Intelligent tjänst Kör webbläsare Dator Browser Stoppad cisvc Indexing Service Stoppad ClipSrv Exchange Map Server Stoppad clr_optimizatio... .NET Runtime Optimization Service v... Stoppad COMSysApp COM+ System Application Kör CryptSvc Cryptographic Services Kör DcomLaunch Kör DCOM-serverprocesser Kör DHCP DHCP Client...

För att ändra formatet på utdata, skicka den till lämplig Format-cmdlet. Till exempel kommer följande kommando att lista tjänster som använder Format-List-cmdleten:

PS C:\> Få service | Format-List Name: Alerter DisplayName: Alerter Status: Stopped DependentServices: () ServicesDependedOn: (LanmanWorkstation) CanPauseAndContinue: False CanShutdown: False CanStop: False ServiceType: Win32ShareProcess Name: ALG DisplayName: Application Level Gateway Dependen Service Status: RunningOn (DependenServices Status: RunningOn) : () CanPauseAndContinue: False CanShutdown: False CanStop: True ServiceType: Win32OwnProcess . . .

Som du kan se visar listformatet mer information om varje tjänst än tabellformatet (istället för tre kolumner med data för varje tjänst, visar listformatet nio rader med data). Detta betyder dock inte att Format-List-cmdleten hämtar ytterligare information om tjänster. Dessa data finns i objekten som returneras av Get-Service-cmdleten, men standardcmdleten Format-Table kasserar den eftersom den inte kan visa mer än tre kolumner.

När du formaterar utdata med cmdletarna Format-List och Format-Table, kan du ange namnen på objektets egenskaper som ska visas (kom ihåg att Get-Member cmdleten som diskuterades tidigare låter dig se listan över egenskaper som ett objekt har) . Till exempel:

PS C:\> Få service | Format-List Name, Status, CanStop Namn: Alerter Status: Stoppad CanStop: False Name: ALG Status: Running CanStop: True Name: AppMgmt Status: Stoppad CanStop: False . . .

Du kan visa alla egenskaper för objekt med hjälp av parametern *, till exempel:

PS C:\> Få service | format-tabell*

Omdirigering av utdatainformation

PowerShell tillhandahåller flera cmdlets som du kan använda för att styra utdata. Dessa cmdlets börjar med ordet Out , och du kan se en lista över dem så här:

PS C:\> Hämta-kommando ut-* | Format-Tabell Namn Namn ---- Out-Default Out-File Out-Host Out-Null Out-Printer Out-String

Som standard skickas utdatainformation till Out-Default-cmdleten, som i sin tur delegerar allt arbete med att visa strängar till Out-Host-cmdleten. För att förstå denna mekanism måste du komma ihåg att PowerShell-arkitekturen innebär en skillnad mellan den faktiska skalkärnan (kommandotolken) och huvudapplikationen (värden) som använder denna kärna. I princip kan vilken applikation som helst som implementerar ett antal speciella gränssnitt som låter dig tolka informationen från PowerShell korrekt fungera som den huvudsakliga. I vårt fall är värdapplikationen konsolfönstret i vilket vi beskjuter, och Out-Host-cmdleten skickar utdata till detta konsolfönster.

Paging-parametern för Out-Host-cmdlet, liksom more-kommandot för Cmd.exe-tolken, låter dig paginera information, till exempel:

Få-hjälp Get-Process –Fullständig | Out-Host-Paging

Spara data till en fil

Out-File-cmdleten låter dig dirigera utdata till en textfil istället för ett konsolfönster. Omdirigeringsoperatorn (>) löser ett liknande problem, men Out-File-cmdleten har flera ytterligare parametrar som kan användas för att mer flexibelt styra utdata: ställ in filkodningstypen (Kodningsparameter), ställ in längden på utdatarader i tecken ( Width parameter), välj det läge som skriver över filen (parametrarna Append , noClobber ). Till exempel kommer följande kommando att skicka information om de tjänster som är registrerade på datorn till filen C:\service.txt, och denna fil kommer att skrivas i ASCII-format.

Trots att PowerShell är ett konsolspråk, är det ibland nödvändigt att meddela användaren från ett PowerShell-skript om en viss händelse eller behovet av att utföra en viss åtgärd. Visa till exempel ett meddelande om att ett långt PoSh-skript har slutförts eller om någon viktig händelse inträffar.

Det enklaste sättet att visa en anpassad testruta är genom Windows Scripting Subsystem - Wscript.

Följande kod kommer att visa en normal textruta med den önskade texten och en OK-knapp.

$wshell = New-Object -ComObject Wscript.Shell
$Output = $wshell.Popup("Skript för rapportgenerering slutfört")

Med olika egenskaper hos Popup-metoden kan du anpassa utseendet på den modala meddelanderutan. I synnerhet kan du returnera resultatet av användarens svar på frågan (Ja / Nej) till skriptet.

$Output = $wshell.Popup("Rapportgenereringsskriptet är klart! Vill du visa det på skärmen?",0,"Rapporten är klar",4+32)

Den allmänna syntaxen och parametrarna för Popup-metoden är:

Dyka upp( ,,,<Type>) </b></p><p>Parametrar:</p><ul><li><Text>— sträng, meddelandetext.</li><li><SecondsToWait>- valfritt, antal. Antalet sekunder efter vilket fönstret stängs automatiskt.</li><li><Title>- valfritt, sträng. Titeltexten på meddelanderutan.</li><li><Type>- valfritt, antal. En kombination av flaggor som definierar typen av knappar och ikon. Möjliga flaggvärden: <ul><li>0 - OK-knapp.</li><li>1 - Knapparna OK och Avbryt.</li><li>2 - Knapparna Stopp, Upprepa, Hoppa över.</li><li>3 — knappar Ja, Nej, Avbryt.</li><li>4 - Ja- och Nej-knappar.</li><li>5 - Knapparna Gör om och Avbryt.</li><li>16 - Stoppikon.</li><li>32 - Frågeikon.</li><li>48 - Utropssymbol.</li><li>64 - Informationsikon.</li> </ul></li> </ul><p>Beskrivning: Returnerar ett heltalsvärde som anger vilken knapp som trycktes av användaren. Möjliga värden:</p><ul><li>-1 - timeout.</li><li>1 - OK-knapp.</li><li>2 - Avbryt-knapp.</li><li>3 - Stoppknapp.</li><li>4 - Upprepa-knapp.</li><li>5 - Hoppa över-knapp.</li><li>6 - Ja-knapp.</li><li>7 - Ingen knapp.</li> </ul><p>Mer attraktiva och tilltalande för ögat popup-meddelanden (ballonger) kan visas i Windows 7, 8.1 och 10 via Windows Forms API. Följande PowerShell-kod kommer att visa ett popup-meddelande bredvid Windows 10-meddelandefältet, som automatiskt försvinner efter 10 sekunder.</p><p>Add-Type -AssemblyName System.Windows.Forms <br>$global:balmsg = New-Object System.Windows.Forms.NotifyIcon <br>$path = (Get-Process -id $pid).Sökväg <br>$balmsg.Icon = ::ExtractAssociatedIcon($path) <br>$balmsg.BalloonTipIcon = ::Varning <br>$balmsg.BalloonTipText = "Detta är ballongmeddelandetexten för en Windows 10-användare" <br>$balmsg.BalloonTipTitle = "(!LANG:Varning $Env:USERNAME"!} <br>$balmsg.Visible = $true <br>$balmsg.ShowBalloonTip(10000)</p><p><img src='https://i0.wp.com/winitpro.ru/wp-content/uploads/2018/10/vsplyvayushee-uvedomlenie-v-powershell.png' width="100%" loading=lazy loading=lazy></p><p>Dessutom, för att skapa färgglada popup-meddelanden i Windows 10 (PowerShell 5.0+), kan du använda den separata BurntToast PowerShell-modulen från PowerShell-galleriet.</p><p>Modulen installeras från onlineförvaret med: <br>Installera-Modul - Namn BurntToast</p><p>Nu, till exempel, i den tidigare övervägda, kan du lägga till en färgstark avisering:</p><p>New-BurntToastNotification -Text "Kopplad från Wi-Fi-nätverket", "Du har kopplats bort från Wi-Fi-nätverket eftersom din enhet var ansluten till en höghastighets Ethernet-anslutning." -AppLogo C:\PS\changenetwork.png</p><p>Så nu vet du hur du visar ett användarmeddelande via PowerShell. Om användaren har högtalare kan du till och med spela en låt för dem:</p><p>::pip(440 500) <br>::pip(440 500) <br>::pip(440 500) <br>::pip(349 350) <br>::pip(523 150) <br>::pip(440 500) <br>::pip(349 350) <br>::pip(523 150) <br>::pip(440 1000) <br>::pip(659 500) <br>::pip(659 500) <br>::pip(659 500) <br>::pip(698 350) <br>::pip(523 150) <br>::pip(415 500) <br>::pip(349 350) <br>::pip(523 150) <br>::pip(440 1000) <br>::pip(880 500) <br>::pip(440 350) <br>::pip(440 150) <br>::pip(880 500) <br>::pip(830 250) <br>::pip(784 250) <br>::pip(740 125) <br>::pip(698 125) <br>::pip(740 250) <br>::pip(455 250) <br>::pip(622 500) <br>::pip(587 250) <br>::pip(554 250) <br>::pip(523,125) <br>::pip(466 125) <br>::pip(523 250) <br>::pip(349 125) <br>::pip(415 500) <br>::pip(349 375) <br>::pip(440,125) <br>::pip(523 500) <br>::pip(440 375) <br>::pip(523,125) <br>::pip(659 1000) <br>::pip(880 500) <br>::pip(440 350) <br>::pip(440 150) <br>::pip(880 500) <br>::pip(830 250) <br>::pip(784 250) <br>::pip(740 125) <br>::pip(698 125) <br>::pip(740 250) <br>::pip(455 250) <br>::pip(622 500) <br>::pip(587 250) <br>::pip(554 250) <br>::pip(523,125) <br>::pip(466 125) <br>::pip(523 250) <br>::pip(349 250) <br>::pip(415 500) <br>::pip(349 375) <br>::pip(523,125) <br>::pip(440 500) <br>::pip(349 375) <br>::pip(261 125) <br>::pip(440 1000)</p> <p>När du skriver ett program eller skript kommer alla nybörjare stöta på ett problem där han behöver upprepa koden två gånger och detta kan hjälpas <b>fungerar i powershell</b>. Funktioner kallas även metoder och procedurer. Förutom att de är återanvändbara är de också användbara för att separera en del av ett skript från en annan, även om det körs en gång. Metoderna som beskrivs nedan finns på många språk och fungerar i ett liknande scenario.</p> <h2>Skapande</h2> <p>Föreställ dig att du varje morgon kontrollerar de senaste 50 loggarna under 14 timmar i applikationsloggen med detta kommando:</p><p>Get-EventLog -LogName Application -Newest 50 | där TimeWritten -ge (Get-Date).AddHours(-14)</p><p><img src='https://i2.wp.com/fixmypc.ru/media/uploads/2019/10/10/1.jpg' width="100%" loading=lazy loading=lazy>Kommandot är inte särskilt komplicerat, men snart kommer du att tröttna på att skriva det. För att minska detta arbete kan det delas upp i en separat funktion:</p><p>Funktion Get-DayLog ( Get-EventLog -LogName Application -Newest 50 | där TimeWritten -ge (Get-Date).AddHours(-14) )</p><p>Varje funktion måste nödvändigtvis bestå av tre saker:</p> <ul><li>function - deklarerar och säger att efter den kommer det att finnas ett namn;</li> <li>funktionsnamn - namnet som vi kommer att kalla det. I vårt fall är namnet Get-DayLog;</li> <li>parenteser - betecknar början och slutet av uttrycket.</li> </ul><p>Efter att ha skrivit en funktion kallas den vid namn:</p><p>GetDayLog</p><p><img src='https://i0.wp.com/fixmypc.ru/media/uploads/2019/10/10/2.jpg' width="100%" loading=lazy loading=lazy></p> <p>Med tanke på att vi kan behöva få data inte för de senaste 14 timmarna och mer än 50 dagar, kan vi behöva ändra det genom att skicka parametrar.</p> <h2>namngivning</h2> <p>Det är inte nödvändigt att använda namnet på samma plan som är brukligt i Powershell, det vill säga istället för "Get-DayLog" kan du skriva "daylog". Detta tillvägagångssätt rekommenderas och är en vanlig praxis som hjälper dig att skilja mellan att köra ett tredjepartsprogram och en funktion.</p> <p>Funktioner i Powershell är alltid döpta efter följande. Det första ordet är verb som:</p> <ul><li>Få - få;</li> <li>Ställ in - ändra;</li> <li>Installera - installera;</li> <li>Nytt - skapa.</li> </ul><p>Det andra namnet är ett substantiv, som i fallet med DayLog ovan. Microsoft har en godkänd lista med verb, som finns tillgänglig på länken på engelska. Om du inte följer dessa regler och vill lägga till din funktion (cmdlet eller modul) till ett av förråden, kan det hända att den inte klarar moderering.</p> <h2></h2> <h2>Passerar parametrar</h2> <p>Oftast tar funktioner någon form av objekt och returnerar det. Det kan till exempel vara nödvändigt att ändra tidpunkten när dessa loggar skapas och deras antal. Det finns ingen sådan möjlighet i den befintliga funktionen. Du kan ändra koden varje gång, men det är inte en programmerares tillvägagångssätt. För att den här funktionen ska visas i funktionen måste du lägga till parametrar som den accepterar:</p><p>Funktion Get-DayLog ($param1,$param2) ( Get-EventLog -LogName Application -Newest $param1 | där TimeWritten -ge (Get-Date).AddHours($param2) )</p><p>Funktionsparametrar är omgivna inom parentes och skrivs efter funktionsnamnet och före uttrycket.</p> <p>Nu, för att anropa funktionen, måste du skicka två parametrar:</p><p>Get-DayLog -param1 50 -param2 -14</p><p><img src='https://i1.wp.com/fixmypc.ru/media/uploads/2019/10/10/4.jpg' width="100%" loading=lazy loading=lazy></p> <p>När vi anropar funktionen skickar vi två nödvändiga parametrar med värden. Dessa värden, inuti funktionen, kommer att vara tillgängliga under namnen $param1 och $param2. Vi skickar dessa variabler till kommandot för att ta emot och filtrera loggar.</p> <h3>Ställa in standardvärden</h3> <p>I vår uppgift får vi oftast bara de 50 senaste loggarna och vi vill inte specificera dem varje gång. Om vi ​​inte anger denna parameter i en befintlig funktion får vi ett felmeddelande. För att undvika detta måste du ange ett standardvärde. I exemplet nedan har jag satt $param1 till 50. Den kommer bara att användas om vi inte använder den parametern när vi anropar:</p><p>Funktion Get-DayLog ($param1=50,$param2) ( Get-EventLog -LogName Application -Newest $param1 | där TimeWritten -ge (Get-Date).AddHours($param2) ) Get-DayLog -param2 -7</p><p><img src='https://i0.wp.com/fixmypc.ru/media/uploads/2019/10/10/5.jpg' width="100%" loading=lazy loading=lazy></p> <p>Vi måste alltid ange param2-nyckeln, vilket lägger till lite arbete. För att fixa detta, byt bara ut dem:</p><p>Funktion Get-DayLog ($param2,$param1=50) ( Get-EventLog -LogName Application -Newest $param1 | där TimeWritten -ge (Get-Date).AddHours($param2) ) Get-DayLog -7 1 Get-DayLog -7</p><p><img src='https://i0.wp.com/fixmypc.ru/media/uploads/2019/10/10/7.jpg' width="100%" loading=lazy loading=lazy></p> <p>Som du kan se i exemplet, om vi inte anger nycklarna param1 och param2, är sekvensen viktig, eftersom det är i denna sekvens som de kommer att tilldelas variablerna i funktionerna.</p> <h3>Returnerande värden</h3> <p>Till skillnad från andra språk, om vi tilldelar resultatet av Get-DayLog-funktionen till variabeln $result, kommer den att innehålla värdena:</p><p>$result = GetDayLog -7 1</p><p>Detta kommer att fungera tills vi bestämmer oss för att ändra funktionen genom att tilldela variabler:</p><p>Funktion Get-DayLog ($param2,$param1=50) ( $events = Get-EventLog -LogName Application -Newest $param1 | där TimeWritten -ge (Get-Date).AddHours($param2) ) $result = Get-DayLog -7 $resultat $händelser</p><p>Vi kan inte få resultatet med hjälp av variabeln $result, eftersom funktionen inte visar information, utan lagrar den i variabeln $events. Genom att ringa $events får vi inte heller information, eftersom begreppet "variabelt omfattning" fungerar här.</p> <p>Eftersom funktioner är en separat del av programmet bör all logik och dess variabler inte röra någon annan del av den. Variabel omfattning innebär detsamma. Alla variabler som skapas i funktionen finns kvar i den. Denna situation kan åtgärdas med retur:</p><p>Funktion Get-DayLog ($param2,$param1=50) ( $events = Get-EventLog -LogName Application -Newest $param1 | där TimeWritten -ge (Get-Date).AddHours($param2) returnerar $events ) $result = Get-DayLog -7 $resultat</p><p><img src='https://i0.wp.com/fixmypc.ru/media/uploads/2019/10/10/11.jpg' width="100%" loading=lazy loading=lazy></p> <p>Jag skulle rekommendera att alltid returnera värden via retur istället för att använda utdata med kommandon som Write-Output i en funktion. Att använda retur stoppar funktionen och returnerar ett värde, vilket betyder att den inte ska placeras mitt i logiken om det inte var planerat så.</p> <p>Det kan finnas flera returvärden. Låt oss till exempel skapa en funktion som beräknar lön och skatt:</p><p>Funktion Get-Salary ($Zarplata) ( $nalog = $Zarplata * 0,13 $zarplata_bez_nds = $Zarplata - $nalog return $nalog,$zarplata_bez_nds ) Get-Salary -Zarplata 100000</p><p>Jag returnerade båda värdena separerade med kommatecken. Som standard returneras alltid en array. det är en uppsättning namnlösa parametrar. Vi har redan skrivit om dem mer i detalj.</p> <p>När det gäller matriser, för att lägga till en inskription om lön och skatt, måste du använda index:</p><p>$result = Get-Salary -Zarplata 100000 # Definiera datatyp $result.GetType() Write-Host "detta är lön" $result Write-Host "detta är skatt" $result</p><p><img src='https://i2.wp.com/fixmypc.ru/media/uploads/2019/10/10/13.jpg' width="100%" loading=lazy loading=lazy></p> <p>Alla datatyper kan returneras. Till exempel kan vi använda en annan datatyp hashtabeller, som, till skillnad från arrayer, heter:</p><p>Funktion Get-Salary ($Zarplata) ( $nalog = $Zarplata * 0,13 $zarplata_bez_nds = $Zarplata - $nalog return @("Tax"=$nalog;"Salary"=$zarplata_bez_nds;) ) Get-Salary -Zarplata 1000</p><p><img src='https://i1.wp.com/fixmypc.ru/media/uploads/2019/10/10/14.jpg' width="100%" loading=lazy loading=lazy></p> <h2>Använda Arrays</h2> <h3>Skickar arrayer som parametrar</h3> <p>I tidigare artiklar fanns det många exempel på att arbeta med arrayer och hashtabeller. De, som alla andra datatyper, kan vi överföra till en funktion. Till exempel kan alla Powershell-kommandon som har en datornamn-nyckel köras på distans. De flesta av dessa kommandon kan ta arrayer som värden, vilket betyder att vi inte behöver skicka datornamn ett efter ett.</p> <p>Funktionen tar en array med datornamn och returnerar alla stoppade tjänster. Jag kommer också att förklara den här typen strikt, för tydlighetens skull, även om den inte fungerar ändå:</p><p>Funktion Get-ServiceStopped ($Computers)( $services = Get-Service -Datornamn $Computers | där Status -eq Stoppad returnerar $services ) Get-ServiceStopped "127.0.0.1","localhost"</p><p><img src='https://i0.wp.com/fixmypc.ru/media/uploads/2019/10/10/19.jpg' width="100%" loading=lazy loading=lazy></p> <p>Arrayer fungerar också med index, vilket gör att du kan skicka fler parametrar. Denna metod är inte relevant, men kan någon gång komma väl till pass.</p><p>Funktion Get-ServiceStopped ($Computers)( $services = Get-Service -ComputerName $Computers | där Status -eq $Computers[-1] returnerar $services ) Get-ServiceStopped "127.0.0.1","localhost","Stoppad"</p><h3>Tabellhash</h3> <p>Parametrar för hashtabeller och kan skickas inte bara till en funktion, utan som parametrar till cmdlets. Låt oss lägga till starten av tjänsten till vår funktion om den stoppas:</p><p>Funktion Get-ServiceStopped ($Params)( $services = Get-Service @Params | där Status -eq Stoppad $services = Start-Service $services return $services ) Get-ServiceStopped @(Name="WinRM";ComputerName=@( "127.0.0.1", "lokal värd"))</p><p>@-tecknet i kommandot deklarerar att hashtabelldata kommer att användas som kommandoparametrar. Det är viktigt att deras namn motsvarar de verkliga parametrarna.</p> <h2>Villkor</h2> <p>Det finns inga begränsningar för användningen av villkoren. Detta är ganska praktiskt när en funktion måste returnera olika värden.</p> <h3></h3> <p>Nedan är ett exempel där ett annat svar kommer att returneras beroende på laddningshastigheten för huvuddelen av webbplatsen. Om svarshastigheten är mindre än 76 millisekunder, kommer ett annat resultat att returneras vid ett längre svar:</p><p>Funktion Get-SiteResponse ( # Starta nedräkningen $start_time = Get-Date # Utför begäran $request = Invoke-WebRequest -Uri "https://site" # Fixa slutförandet av exekveringen $end_time = Get-Date # Beräkna tidsskillnad $result = $end_time - $start_time # Kontrollera och returnera resultatet if ($result.Milliseconds -lt 76) ( return "Svarshastigheten är normal" + $result.Millisekunder) else( return "Webbplatsen svarar under en lång tid " + $result.Milliseconds ) ) Get- SiteResponse</p><p><img src='https://i1.wp.com/fixmypc.ru/media/uploads/2019/10/11/20.jpg' width="100%" loading=lazy loading=lazy></p> <h3>växla</h3> <p>Vi har redan pratat om i tidigare artiklar. Kort sagt, dessa är mer bekväma förhållanden. Med det föregående exemplet, men med Switch, skulle det se ut så här:</p><p>Funktion Get-SiteResponse ( # Starta nedräkningen $start_time = Get-Date # Execute the request $request = Invoke-WebRequest -Uri "https://site" # Fixa slutet av exekveringen $end_time = Get-Date # Beräkna tidsskillnad $result = $end_time - $start_time # Testa och returnera resultatomkopplaren($result.Milliseconds) (($PSItem -le 76) (retur "Speed ​​​​is normal" + $result.Milliseconds) default ( return " Webbplatsen tar lång tid att svara" + $result. Millisekunder ) ) ) Get-SiteResponse</p><p><img src='https://i1.wp.com/fixmypc.ru/media/uploads/2019/10/11/21.jpg' width="100%" loading=lazy loading=lazy>Ett annat exempel på Switch är ett funktionsanrop beroende på de angivna parametrarna. I exemplet nedan anropar jag en funktion som innehåller en Switch. Jag skickar datornamnet till den här funktionen, som kontrolleras för att nämna de angivna fraserna och anropar lämplig funktion. Varje funktion som ställer in uppdateringar returnerar ett värde till switchen och returnerar sedan inuti den:</p><p>Funktion Install-SQLUpdates ( # gör installationen returnerar "Installation av uppdateringar till SQL-servern lyckades" ) funktion Install-ADUpdates ( # gör installationen returnerar "Installation av uppdateringar till AD-servern lyckades") funktionen Install-FileServerUpdates ( # gör installationen installation return "Installation av uppdateringar till filservern lyckades" ) funktion Make-Switch ($computer) ( # Kontrollerar datornamnet $result = switch($computer)( ($computer -like "SQL*") (Install-SqlUpdates ) ($computer -like " AD*") (Install-ADUpdates) ($computer -like "FileServer*") (Install-FileServerUpdates) standard ("Det finns ingen sådan datortyp") ) return $result ) Make-Switch "AD1"</p><p><img src='https://i1.wp.com/fixmypc.ru/media/uploads/2019/10/11/22.jpg' width="100%" loading=lazy loading=lazy></p> <p>Med switch är det också bekvämt att skicka booleska värden. I exemplet nedan, om -On-tangenten är angiven, kommer tjänsten att slås på, och om den inte finns där, stängs den av:</p><p>Funktion Switch-ServiceTest ($on) ( if ($on) (Write-Output "Service On") else ("Service Off") ) Switch-ServiceTest -On Switch-ServiceTest</p><p><img src='https://i1.wp.com/fixmypc.ru/media/uploads/2019/10/11/26.jpg' width="100%" loading=lazy loading=lazy></p> <h2>Överför via en transportör eller pipeline</h2> <p>Du måste ha arbetat igenom Powershell-kommandon som gjorde att du kunde använda pipelinen så här:</p><p>Get-Process -Name *TestProc* | Stoppa process</p><p>Om vi ​​vill använda tillvägagångssättet som beskrivs ovan genom att skapa nya kommandon som funktioner, kommer pipelinen inte att fungera:</p><p>Funktion Get-SomeNum ( # Generera nummer $num = Get-Random -Minimum 5 -Max 10 returnera $num ) funktion Plus-SomeNum ($num) ( Skriv-värd "Lägg till nummer " $num $num += $num returnera $ num ) Get-SomeNum Plus-SomeNum 5 Get-SomeNum | Plus-SomeNum</p><p><img src='https://i0.wp.com/fixmypc.ru/media/uploads/2019/10/12/35.jpg' width="100%" loading=lazy loading=lazy></p> <p>Genom att utföra följande kommando kan vi se att värdena som kan tas emot genom pipelinen är markerade med ett speciellt attribut:</p><p>Få-hjälp Stoppa-process -Parameternamn</p><p>Det finns bara två sådana attribut:</p> <ul><li><b>ValueFromPipelineByPropertyName</b>- få ett värde från pipelinen med namn;</li> <li><b>ValueFromPipeline</b>- tar endast emot värden genom pipelinen.</li> </ul><p>Dessutom måste vi inuti vår funktion lägga till ett speciellt processblock. Vårt manus kommer att se ut så här:</p><p>Funktion Get-SomeNum ( $num = Get-Random -Minimum 5 -Max 10 return $num ) funktion Plus-SomeNum ( Param ( $num) process ( Write-Host "Add number " $num $num += $num return $ num ) ) 1..5 | Plus-SomeNum Get-SomeNum | Plus-SomeNum</p><p><img src='https://i1.wp.com/fixmypc.ru/media/uploads/2019/10/12/37.jpg' width="100%" loading=lazy loading=lazy></p> <p>Ett funktionstilläggsattribut som lägger till viss funktionalitet till funktioner så att de kan fungera som ett kommando.</p> <p>Om vi ​​inte hade specificerat Process-blocket, skulle funktionen endast ha returnerat det sista resultatet från arrayen 1..5:</p> <p><img src='https://i0.wp.com/fixmypc.ru/media/uploads/2019/10/12/39.jpg' width="100%" loading=lazy loading=lazy></p> <p>Om våra kommandon kommer att vara av kritisk karaktär, såsom radering, eller flera värden kan skickas genom pipelinen, är det värt att använda attributet ValueFromPipelineByPropertyName. På detta sätt kommer vi att utesluta träffar genom pipeline av ett slumpmässigt värde. I exemplet nedan ändrade jag</p><p>Funktion Get-SomeNum ( $num = Get-Random -Minimum 5 -Maximum 10 $object = @(num=$num) return $object ) funktion Plus-SomeNum ( Param ( $num) process ( Write-Host "Add number " $num $num += $num return $num ) ) Get-SomeNum | Plus-SomeNum @(num=5) | Plus-SomeNum @(bad=5) | Plus-SomeNum</p><p><img src='https://i1.wp.com/fixmypc.ru/media/uploads/2019/10/12/40.jpg' width="100%" loading=lazy loading=lazy></p> <p>Som redan nämnts accepterar ValueFromPipelineByPropertyName endast namngivna parametrar och i fallet med namnet "dåligt" får vi ett felmeddelande:</p> <ul><li><span>Det går inte att binda ett indataobjekt till några kommandoparametrar eftersom kommandot inte accepterar pipeline-ingång</span></li> <li><span>Ingångsobjektet kan inte bindas till några parametrar för kommandot, antingen eftersom kommandot inte tar pipeline-ingång eller att ingången och dess egenskaper inte matchar någon av parametrarna som tar pipeline-ingång.</span></li> </ul><p>Dessutom kan vi inte skicka namngivna parametrar genom tabellens hash, bara genom pscustomobject.</p> <p>Du kan ange två attribut samtidigt så här:</p><p>Detta gör att värdet kan användas med eller utan ett namn om ett sådant anges. Detta kommer inte att rädda dig från situationen om du skickar en parameter med ett annat namn:</p> <p><img src='https://i2.wp.com/fixmypc.ru/media/uploads/2019/10/12/41.jpg' width="100%" loading=lazy loading=lazy></p> <h3>Att skicka flera värden genom en pipeline</h3> <p>Tänk till exempel på en situation där vi behöver skicka två värden genom en pipeline. Om Get-SomeNum returnerar en array kommer varje nummer att passera genom pipelinen separat. Detta är ytterligare en anledning att använda namngivna parametrar:</p><p>Funktion Get-SomeNum ( $number1 = Get-Random -Minimum 5 -Maximum 10 $number2 = Get-Random -Minimum 1 -Maximum 5 $object = @(number1=$number1;num2=$number2) return $object ) funktion Plus -SomeNum ( Param ( $num1, $num2) börjar ($num1 += $num1 $num2 = $num2 * $num2) process ( return @("Resultat av addition"=$num1; "Resultat av multiplikation"=$num2 ) ) ) Get-SomeNum | Plus-SomeNum</p> <script>document.write("<img style='display:none;' src='//counter.yadro.ru/hit;artfast_after?t44.1;r"+ escape(document.referrer)+((typeof(screen)=="undefined")?"": ";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth? screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+";h"+escape(document.title.substring(0,150))+ ";"+Math.random()+ "border='0' width='1' height='1' loading=lazy loading=lazy>");</script> </div><div class="clear"></div> <script type="text/javascript"> document.getElementById('hc_full_comments').innerHTML = ''; </script><br /><br /><noindex><p align="center"><center> <div id="meta_news_block1111" style="text-align: center;"></div></center> </p> <br /><br /> <p align="center"> </p> </noindex> </div> </div> <div id="sidebar"> <div class="clear"></div><br /> <h2 class="front" style="margin:15px 0 5px 0">Populära artiklar</h2> <div class="tabcont"> <ol> <li><a href="https://gtavrl.ru/sv/skachat-s-mnozhestvom-interfeisov-audiopleer-foobar2000-foobar2000-muzyka-bez-prikras/">Foobar2000 - musik utan utsmyckning</a></li> <li><a href="https://gtavrl.ru/sv/programma-diagnostiki-apparatnogo-obespecheniya-diagnostika-kompyutera-na/">Diagnostisera en dator för problem</a></li> <li><a href="https://gtavrl.ru/sv/chto-budet-esli-polozhit-telefon-v-mikrovolnovku-chto-mozhet-bytovaya-mikrovolnovka-mozhno-li-zaryadit/">Vad kan en hushållsmikrovågsugn?</a></li> <li><a href="https://gtavrl.ru/sv/samyi-dorogoi-sabvufer-luchshie-aktivnye-sabvufery-dlya-avto-i/">De bästa aktiva subwoofrarna för bilar och deras recension</a></li> <li><a href="https://gtavrl.ru/sv/vydvizhnaya-qwerty-klaviatura-sovremennye-knopochnye-smartfony/">Moderna smartphones med tryckknapp: inte en enda sensor</a></li> </ol> </div> <h2 class="front" style="margin:15px 0 5px 0">Senaste artiklarna</h2> <div class="tabcont"> <ol> <li><a href="https://gtavrl.ru/sv/qwerty-smartfony-telefony-s-qwerty-klaviaturoi-dlya-teh-kto-pishet/">Telefoner med qwerty-tangentbord</a></li> <li><a href="https://gtavrl.ru/sv/samye-bolshie-sabvufery-v-mire-samyi-bolshoi-sabvufer-v-mire-ceny/">Den största subwoofern i världen</a></li> <li><a href="https://gtavrl.ru/sv/sotovye-telefony-vodonepronicaemye-protivoudarnye-nokia/">Den bästa smartphonen utan kamera: en översikt över modeller</a></li> <li><a href="https://gtavrl.ru/sv/elektronnye-plat-zhnye-sistemy-i-koshelki-dlya-vvoda-vyvoda-deneg-iz/">Betalsystem Vilka betalningssystem finns</a></li> <li><a href="https://gtavrl.ru/sv/kto-pridumal-eksel-microsoft-office-excel-chto-eto-chto-takoe-excel-dlya/">Microsoft Office Excel - vad är det?</a></li> <li><a href="https://gtavrl.ru/sv/kak-priobresti-hakerskie-navyki-kak-priobresti-hakerskie-navyki-chto/">Hur man lär sig hackning Vad du behöver veta för att bli en hacker</a></li> <li><a href="https://gtavrl.ru/sv/chto-v-noutbuke-mozhno-proapgreidit-modernizaciya-staryh/">Uppgradering av gamla komponenter Uppgradering av laptop RAM</a></li> </ol> </div> <div class="widget" id="ajdg_grpwidgets-3"> <div class="g g-9"> <div class="g-single a-27"> <script> jQuery(function() { window.onscroll = function() { height_scroll = jQuery(document).scrollTop(); height = jQuery(document).height(); height50 = height / 2; if (height_scroll >= height50) { jQuery("#site-code-block-22").fadeIn(1200); document.getElementById('site-code-block-22').style.display = 'block'; jQuery("#site-code-block-23").fadeOut(1200); document.getElementById('site-code-block-23').style.display = 'none'; } else { jQuery("#site-code-block-22").fadeOut(1200); document.getElementById('site-code-block-22').style.display = 'none'; document.getElementById('site-code-block-23').style.display = 'block'; jQuery("#site-code-block-23").fadeIn(1200); } }; }); </script> <div class="site-code-block prma-count" data-rel="cb_23" id="site-code-block-23" style=""> </div> <div class="site-code-block prma-count" data-rel="cb_22" id="site-code-block-22" style=""> </div> </div> </div> </div> <div class="clear"></div> <br /> <center> <div style="color: #333333; font-size: 11px;"> </div> </center> <div class="clear"></div> </div> <div class="clear"></div> </div> </div> </div>  <br /><br /> <div id="footeri"> <div id="footer"> <div class="footer-sec"> <h6>Avsnitt</h6> <ul> <li><a href="https://gtavrl.ru/sv/category/youtube/">Youtube</a></li> <li><a href="https://gtavrl.ru/sv/category/facebook/">Facebook</a></li> <li><a href="https://gtavrl.ru/sv/category/twitter/">Twitter</a></li> <li><a href="https://gtavrl.ru/sv/category/tips/">Råd</a></li> <li><a href="https://gtavrl.ru/sv/category/useful-tips/">Hjälpsamma ledtrådar</a></li> <br /> </ul> </div> <div class="footer-sec"> <h6>Sidor</h6> <ul> <li><a href="">om projektet</a></li> <noindex> <li><a href="" >RSS-nyheter</a></li> </noindex> </ul><br /><br /><br /> <h6>Specialprojekt</h6> <ul> <li><a href="">Ta kontakt med oss</a></li> </ul> </div> <div id="footer-top"> <h6>Kontakter</h6> <ul> <li><a href="">Annonsering på hemsidan</a></li> <li><a href="">Kontakter</a></li> </div> <div class="clear"></div> </div></div> <div id="bottom"><div class="foot_col1">2022 <a href="https://gtavrl.ru/sv/">gtavrl.ru</a>. </div> <script type="text/javascript">var addthis_config = { "data_track_addressbar":true,"pubid": "ra-58b68bb0f1371607"} ;addthis_config.data_track_addressbar = false;addthis_config.data_track_clickback = false;</script> <script type='text/javascript'> var flag_hide = 0; function hide_direct() { flag_hide = 1; jQuery('#rek_mob_fixed').slideToggle( 'slow' ); var date = new Date(); var expires_hour = 21600000; date.setTime(date.getTime()+expires_hour); showSocial(); Cookies.set('advp_show_me', '1', { expires: date, path: '/'} ); } ; jQuery(function(f){ var element = f('#rek_mob_fixed'); element.delay(8000); f(window).scroll(function(){ if (flag_hide == 0){ var offset_element_for_hide = jQuery('#before_footer').val(); if (offset_element_for_hide != null) { offset_element_for_hide = jQuery('#before_footer'); offset_element_for_hide = jQuery(offset_element_for_hide).offset().top - jQuery(window).height(); } else { offset_element_for_hide = jQuery(document).height(); } //Если рекламный блок более 1000px по ширине, устанавливай фикс. ширину 1000px if (jQuery('#rek_mob_fixed_block').actual('width') >1000) { jQuery('#rek_mob_fixed_block').css({ 'max-width':'1000px'} ); } if(f(this).scrollTop() > 500){ element.fadeIn(0); } if(f(this).scrollTop() < 500 || f(this).scrollTop() > offset_element_for_hide ){ element.fadeOut(0) } if(f(this).scrollTop() + f(this).height() >= f(document).height() && flag_hide == 0 && jQuery('#rek_mob_fixed').is(':visible')) { jQuery('#rek_mob_fixed').slideToggle(100); } } } ); } ); function showSocial(){ if(flag_hide == 1 ) jQuery('#footer-share').slideToggle('slow'); } </script><div id="wondergridgallerylightbox_options" data-skinsfoldername="skins/default/" data-jsfolder="/wp-content/plugins/modesco-wonderplugin-gridgallery/engine/" style="display:none;"></div> <script type='text/javascript' src='https://gtavrl.ru/wp-content/plugins/contact-form-7/includes/js/scripts.js?ver=4.9.2'></script> <script type='text/javascript' src='https://gtavrl.ru/wp-content/plugins/modesco-monica/script.min.js?ver=4.9.1'></script> <script type='text/javascript'> /* <![CDATA[ */ var tocplus = { "visibility_show":"\u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c","visibility_hide":"\u0441\u043a\u0440\u044b\u0442\u044c","width":"100%"} ; /* ]]> */ </script> <script type='text/javascript' src='https://gtavrl.ru/wp-content/plugins/modesco-table-of-contents-plus/front.js?ver=1404'></script> <script type='text/javascript' src='https://gtavrl.ru/wp-content/plugins/page-links-to/js/new-tab.min.js?ver=2.9.8'></script> <script type='text/javascript'> var q2w3_sidebar_options = new Array(); q2w3_sidebar_options[0] = { "sidebar" : "ads-sidebar", "margin_top" : 10, "margin_bottom" : 50, "stop_id" : "before_footer", "screen_max_width" : 0, "screen_max_height" : 0, "width_inherit" : false, "refresh_interval" : 1500, "window_load_hook" : false, "disable_mo_api" : false, "widgets" : ['ajdg_grpwidgets-3'] } ; </script> <script type='text/javascript' src='https://gtavrl.ru/wp-content/plugins/q2w3-fixed-widget/js/q2w3-fixed-widget.min.js?ver=5.0.4'></script> <script type='text/javascript' src='https://gtavrl.ru/wp-content/plugins/youtube-embed-plus/scripts/fitvids.min.js?ver=4.9.1'></script> <script type='text/javascript' src='/wp-includes/js/wp-embed.min.js?ver=4.9.1'></script> <script type="text/javascript"> var _hcwp = _hcwp || []; var _hcobj = { widget_id : 29264, widget : "Bloggerstream",selector: '.hc_counter_comments',platform:"wordpress", } ; _hcwp.push(_hcobj); (function() { if("HC_LOAD_INIT" in window)return; HC_LOAD_INIT = true; var lang = "ru"; var hcc = document.createElement("script"); hcc.type = "text/javascript"; hcc.async = true; hcc.src = ("https:" == document.location.protocol ? "https" : "http")+"://w.hypercomments.com/widget/hc/29264/"+lang+"/widget.js"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hcc, s.nextSibling); } )(); </script> </body> </div> </body> </html>