Bestimmen Sie die installierte PowerShell-Version


2632

Wie kann ich feststellen, welche Version von PowerShell auf einem Computer installiert ist und ob sie überhaupt installiert ist?

Antworten:


3583

Verwenden Sie $PSVersionTable.PSVersiondiese Option , um die Motorversion zu bestimmen. Wenn die Variable nicht vorhanden ist, kann davon ausgegangen werden, dass es sich bei der Engine um eine Version handelt 1.0.

Beachten Sie dies $Host.Versionund (Get-Host).Versionsind nicht zuverlässig - sie geben nur die Version des Hosts wieder, nicht die Engine. PowerGUI, PowerShellPLUS usw. sind alle Hosting-Anwendungen und stellen die Host-Version so ein, dass sie die Produktversion widerspiegelt - was völlig korrekt ist, aber nicht das, wonach Sie suchen.

PS C:\> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
4      0      -1     -1

2
@DanielCassidy - zwei Jahre zu spät zur Party, aber "einige Funktionen sind unerklärlicherweise nicht verfügbar" kann dadurch verursacht werden, dass nur das .Net 3.5 Compact-Framework anstelle des vollständigen Frameworks installiert ist.
Dave Neeley

83
$PSVersionTableist zuverlässiger und gibt $ PSVersion zurück. Sie können auch verwenden $PSVersionTable.PSVersion. Selbst wenn Sie remote mit dem Computer verbunden sind, auf dem eine andere Version ( invoke-command -computername myRemotePC -Credential foo {$host}) ausgeführt wird, wird anscheinend $hostnur die niedrigste Version angezeigt, die für die Serialisierung vereinbart wurde. While $PSVersionTablezeigt die wahre Version an. Hoffe, es würde jemandem helfen ..
Vulkanrabe

16
Scheint $ host.Version ist keine gute Wahl ... Wenn Sie eine Remote-Verbindung zu einem Computer herstellen, auf dem PowerShell 3 ausgeführt wird, erhalten Sie 1.0 zurück, da RemotingHost v1 zu sein scheint. Bei korrekter Verwendung von $ PSVersionTable wird 3 zurückgegeben.
Danny Tuppeny

25
@Starfish Der angezeigte Befehl startet Powershell mithilfe der Eingabeaufforderung. Würde der Befehl nicht einfach mit "Powershell nicht gefunden" fehlerhaft sein, wenn er nicht installiert ist?
jpmc26

9
Ich bin es so leid, hierher zurückzukehren, dass ich einfach notepad $profilegerannt bin und mich hineingeworfen function psver { $PSVersionTable; $PSVersionTable.PSVersion }habe. Ein Nachladen mit . $profileund ich kann einfach psverjederzeit eingeben, um die detaillierten Versionsinformationen und andere Details zu erhalten.
ADTC

432

Ich würde entweder Get-Host oder $ PSVersionTable verwenden . Wie Andy Schneider betont, $PSVersionTablefunktioniert in Version 1 nicht; es wurde in Version 2 eingeführt.

get-host

Name             : ConsoleHost
Version          : 2.0
InstanceId       : d730016e-2875-4b57-9cd6-d32c8b71e18a
UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture   : en-GB
CurrentUICulture : en-US
PrivateData      : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
IsRunspacePushed : False
Runspace         : System.Management.Automation.Runspaces.LocalRunspace

$PSVersionTable

Name                           Value
----                           -----
CLRVersion                     2.0.50727.4200
BuildVersion                   6.0.6002.18111
PSVersion                      2.0
WSManStackVersion              2.0
PSCompatibleVersions           {1.0, 2.0}
SerializationVersion           1.1.0.1
PSRemotingProtocolVersion      2.1

5
Vielen Dank! NB: Auf meinem XP, auf dem ich manuell ein Upgrade von v1 Powershell durchgeführt habe, verweisen die tatsächlichen Ordner- und Registrierungspfade (irreführend?!) Auf v1 NOT v2. Dies ist, wie andere hier angeben, aber es war der Grund, warum ich so besorgt war, ob ich es installiert hatte. Mein Weg ist; C: \ WINDOWS \ system32 \ windowspowershell \ v1.0
AnneTheAgile

4
Wenn $ psversiontable nicht vorhanden ist, können Sie davon ausgehen, dass Sie sich auf Version 1.0 befinden - und hey presto, das beantwortet auch Ihre Frage. $host.versionist nicht zuverlässig - zum Beispiel in Powergui gibt es die Powergui-Host-Version zurück, die nicht mit der Powershell-Engine-Version identisch ist (was erwünscht ist)
x0n

10
Die akzeptierte Antwort lautet "... $ Host.Version und (Get-Host) .Version sind nicht zuverlässig - sie geben nur die Version des Hosts wieder, nicht die Engine" .
Peter Mortensen

99

Sie können sich die eingebaute Variable ansehen $psversiontable. Wenn es nicht existiert, haben Sie V1. Wenn es existiert, erhalten Sie alle Informationen, die Sie benötigen.

1 >  $psversiontable

Name                           Value                                           
----                           -----                                           
CLRVersion                     2.0.50727.4927                                  
BuildVersion                   6.1.7600.16385                                  
PSVersion                      2.0                                             
WSManStackVersion              2.0                                             
PSCompatibleVersions           {1.0, 2.0}                                      
SerializationVersion           1.1.0.1                                         
PSRemotingProtocolVersion      2.1    

96

Um festzustellen, ob PowerShell installiert ist, können Sie die Registrierung auf das Vorhandensein von überprüfen

HKEY_LOCAL_MACHINE\Software\Microsoft\PowerShell\1\Install

und

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3

und, falls vorhanden, ob der Wert 1 ist (für installiert), wie im Blog-Beitrag beschrieben. Überprüfen Sie, ob PowerShell installiert ist und welche Version .

Um die installierte Version von PowerShell zu ermitteln, können Sie die Registrierungsschlüssel überprüfen

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine\PowerShellVersion

und

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine\PowerShellVersion

Um die Version von PowerShell zu ermitteln, die über ein .ps1-Skript installiert wird, können Sie den folgenden Einzeiler verwenden, wie auf PowerShell.com beschrieben, in dem PowerShell-Version ausgeführt wird .

$isV2 = test-path variable:\psversiontable

Dieselbe Site bietet auch eine Funktion zum Zurückgeben der Version:

function Get-PSVersion {
    if (test-path variable:psversiontable) {$psversiontable.psversion} else {[version]"1.0.0.0"}
}

4
Nützlich, weil ich auf einem Windows 2003-Server den Startmenüeintrag für PowerShell nicht finden konnte (er war vorhanden, aber nicht offensichtlich), aber der Registrierungsschlüssel hat meine Frage beantwortet.
Ganzheitlicher Entwickler

7
Für PowerScript 3.0 scheint es einen neuen Eintrag zu geben, HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ PowerShell \ 3 (zusätzlich zu HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ PowerShell \ 1 ). In diesem Fall scheint der richtige Ort zum Abrufen der Version HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ PowerShell \ 3 \ PowerShellEngine \ PowerShellVersion zu sein (Beispielwert ist "3.0").
Peter Mortensen

48

Sie können die Version direkt mit nur einer Zeile überprüfen, indem Sie PowerShell extern aufrufen , z. B. über die Eingabeaufforderung

powershell -Command "$PSVersionTable.PSVersion"

Bis nach @psaul Sie können tatsächlich einen Befehl haben , die von Agnostiker ist , woher es kam (CMD, Powershell oder Pwsh). Danke für das.

powershell -command "(Get-Variable PSVersionTable -ValueOnly).PSVersion"

Ich habe getestet und es hat sowohl auf CMD als auch auf PowerShell einwandfrei funktioniert.

Bild


Bei diesem Versuch wird der schreckliche Fehler angezeigt: "System.Collections.Hashtable.PSVersion: Der Begriff" System.Collections.Hashtable.PSVersion "wird nicht als Name eines Cmdlets, einer Funktion, einer Skriptdatei oder eines funktionsfähigen Programms erkannt Wenn Sie den Namen buchstabieren oder einen Pfad angegeben haben, überprüfen Sie, ob der Pfad korrekt ist, und versuchen Sie es erneut. " Funktioniert also nicht immer
Gonmator

Ich bin froh, dass Sie darauf hingewiesen haben, da es gut ist, die Eckfälle zu kennen, aber ich denke, es funktioniert immer noch für die Mehrheit der Menschen.
Patrick Bard

@Gonmator Man würde denken, PowerShell würde sich mit diesem Befehl genauso verhalten, aber leider nicht. Ich habe versucht, die Syntax so zu korrigieren, dass sie agnostisch zwischen cmdund powershellohne Erfolg funktioniert . Ich hätte das gleiche Verhalten auch erwartet. :)
tresf

3
@tresf (und @Gonmator) Sie können dies agnostisch von CMD, PowerShell oder sogar Pwsh (PS 6.0) ausführen, aber Sie müssen dieses Formular verwenden: Powershell-Befehl "(Get-Variable PSVersionTable -ValueOnly) .PSVersion" (das wird Arbeit in allen Fällen)
PSaul

Auch auf dem Mac getestet. pwsh -Command "(Get-Variable PSVersionTable -ValueOnly).PSVersion" funktioniert super.
Tresf

37

Sie können überprüfen, ob die Windows PowerShell-Version installiert ist, indem Sie die folgende Prüfung durchführen:

  1. Klicken Sie auf Start, auf Alle Programme, klicken Sie auf Zubehör, klicken Sie auf Windows PowerShell und dann auf Windows PowerShell.
  2. Geben Sie in der Windows PowerShell-Konsole an der Eingabeaufforderung den folgenden Befehl ein und drücken Sie die EINGABETASTE:

    Get-Host | Select-Object Version

Sie sehen eine Ausgabe, die folgendermaßen aussieht:

Version
-------
3.0

http://www.myerrorsandmysolutions.com/how-to-verify-the-windows-powershell-version-installed/


1
Sie gehen davon aus, dass Powershell mit Standardoptionen installiert wurde und die Verknüpfungen nicht aus dem Startmenü entfernt wurden. Verwenden Sie besser den Registrierungstest.
Xalorous

Ich denke, wenn Sie PowerShell zuerst verwenden müssen, versuchen Sie, es als Standard auszuführen. Es sollte installiert werden. Wenn Sie das Symbol beim Suchen nicht finden, versuchen Sie es möglicherweise über die Eingabeaufforderung auszuführen. Ich glaube nicht, dass Sie von der Registrierung ausgehen.
Finsternisse

6
Die akzeptierte Antwort lautet "... $ Host.Version und (Get-Host) .Version sind nicht zuverlässig - sie geben nur die Version des Hosts wieder, nicht die Engine" .
Peter Mortensen

21

Die von Microsoft empfohlene vorwärtskompatible Methode zur Überprüfung, ob PowerShell installiert ist, und zur Ermittlung der installierten Version besteht darin, zwei bestimmte Registrierungsschlüssel zu überprüfen . Ich habe die Details hier reproduziert, falls der Link unterbrochen wird.

Laut der verlinkten Seite:

Abhängig von anderen Registrierungsschlüsseln oder Versionen von PowerShell.exe oder dem Speicherort von PowerShell.exe kann nicht garantiert werden, dass dies langfristig funktioniert.

Überprüfen Sie in der Registrierung , ob eine Version von PowerShell installiert ist:

  • Schlüsselposition: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1
  • Wert Name: Installieren
  • Werttyp: REG_DWORD
  • Wertdaten: 0x00000001 (1

Überprüfen Sie in der Registrierung , ob in Version 1.0 oder 2.0 von PowerShell Folgendes installiert ist:

  • Schlüsselposition: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\PowerShell\1\PowerShellEngine
  • Wertname: PowerShellVersion
  • Werttyp: REG_SZ
  • Wertdaten: <1,0 | 2,0>

5
Für PowerShell 3.0 scheint es eine neue zu geben: HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ PowerShell \ 3 .
Peter Mortensen

11

Ich fand den einfachsten Weg, um zu überprüfen, ob installiert war:

  • Führen Sie eine Eingabeaufforderung aus (Start, Ausführen cmd, dann OK).
  • Geben Sie powershelldann die Eingabetaste ein. Sie sollten dann die PowerShell- PSEingabeaufforderung erhalten:

C:\Users\MyUser>powershell

Windows PowerShell
Copyright (C) 2009 Microsoft Corporation. All rights reserved.

PS C:\Users\MyUser>

Sie können die Version dann an der PowerShell-Eingabeaufforderung überprüfen, indem Sie Folgendes eingeben $PSVersionTable.PSVersion:

PS C:\Users\MyUser> $PSVersionTable.PSVersion

Major  Minor  Build  Revision
-----  -----  -----  --------
2      0      -1     -1

PS C:\Users\MyUser>

Geben exitSie ein, wenn Sie zur Eingabeaufforderung exitzurückkehren möchten ( erneut, wenn Sie auch die Eingabeaufforderung schließen möchten).

Informationen zum Ausführen von Skripten finden Sie unter http://ss64.com/ps/syntax-run.html .


3
Wie bei der akzeptierten Antwort gibt dies für PowerShell 1.0 nichts zurück. Die Registrierungsmethode ist expliziter.
Peter Mortensen

4
Wenn Powershell nicht im Pfad enthalten war, vermittelt diese Version den falschen Eindruck, dass sie nicht installiert ist. Die Registrierungsmethode bietet vollständige Informationen. Präsenz und Version.
Xalorous

9

$host.versionist einfach falsch / unzuverlässig. Dies gibt Ihnen die Version der ausführbaren Hosting-Datei (Powershell.exe, Powergui.exe, Powershell_ise.exe, Powershellplus.exe usw.) und nicht die Version der Engine selbst.

Die Motorversion ist in enthalten $psversiontable.psversion. Für PowerShell 1.0 ist diese Variable nicht vorhanden. Wenn diese Variable nicht verfügbar ist, kann davon ausgegangen werden, dass die Engine offensichtlich 1.0 ist.


9

Verwenden:

$psVersion = $PSVersionTable.PSVersion
If ($psVersion)
{
    #PowerShell Version Mapping
    $psVersionMappings = @()
    $psVersionMappings += New-Object PSObject -Property @{Name='5.1.14393.0';FriendlyName='Windows PowerShell 5.1 Preview';ApplicableOS='Windows 10 Anniversary Update'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.1.14300.1000';FriendlyName='Windows PowerShell 5.1 Preview';ApplicableOS='Windows Server 2016 Technical Preview 5'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10586.494';FriendlyName='Windows PowerShell 5 RTM';ApplicableOS='Windows 10 1511 + KB3172985 1607'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10586.122';FriendlyName='Windows PowerShell 5 RTM';ApplicableOS='Windows 10 1511 + KB3140743 1603'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10586.117';FriendlyName='Windows PowerShell 5 RTM 1602';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8.1, and Windows 7 SP1'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10586.63';FriendlyName='Windows PowerShell 5 RTM';ApplicableOS='Windows 10 1511 + KB3135173 1602'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10586.51';FriendlyName='Windows PowerShell 5 RTM 1512';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8.1, and Windows 7 SP1'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10514.6';FriendlyName='Windows PowerShell 5 Production Preview 1508';ApplicableOS='Windows Server 2012 R2'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.10018.0';FriendlyName='Windows PowerShell 5 Preview 1502';ApplicableOS='Windows Server 2012 R2'}
    $psVersionMappings += New-Object PSObject -Property @{Name='5.0.9883.0';FriendlyName='Windows PowerShell 5 Preview November 2014';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows 8.1'}
    $psVersionMappings += New-Object PSObject -Property @{Name='4.0';FriendlyName='Windows PowerShell 4 RTM';ApplicableOS='Windows Server 2012 R2, Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8.1, and Windows 7 SP1'}
    $psVersionMappings += New-Object PSObject -Property @{Name='3.0';FriendlyName='Windows PowerShell 3 RTM';ApplicableOS='Windows Server 2012, Windows Server 2008 R2 SP1, Windows 8, and Windows 7 SP1'}
    $psVersionMappings += New-Object PSObject -Property @{Name='2.0';FriendlyName='Windows PowerShell 2 RTM';ApplicableOS='Windows Server 2008 R2 SP1 and Windows 7'}
    foreach ($psVersionMapping in $psVersionMappings)
    {
        If ($psVersion -ge $psVersionMapping.Name) {
            @{CurrentVersion=$psVersion;FriendlyName=$psVersionMapping.FriendlyName;ApplicableOS=$psVersionMapping.ApplicableOS}
            Break
        }
    }
}
Else{
    @{CurrentVersion='1.0';FriendlyName='Windows PowerShell 1 RTM';ApplicableOS='Windows Server 2008, Windows Server 2003, Windows Vista, Windows XP'}
}

Sie können das detaillierte Skript unter So ermitteln Sie die installierte PowerShell-Version herunterladen .


8

Der einfachste Weg, diese Seite zu vergessen und nie wieder dorthin zurückzukehren, besteht darin, Folgendes zu lernen Get-Variable:

Get-Variable | where {$_.Name -Like '*version*'} | %{$_[0].Value}

Es ist nicht erforderlich, sich jede Variable zu merken. Nur Get-Variableist genug (und "Es sollte etwas über die Version sein").


8
Welches ist das gleiche wie$PSVersionTable
orad

6
Auf der Suche nach der PS-Version? Geben Sie $ PSVersion [tab] [enter] ein. Erledigt. Ich muss mich an nichts erinnern :)
orad

1
Dies ist wirklich nur dann nützlich, wenn man mit den verwendeten Piping-Tricks sehr vertraut ist. Auf keinen Fall kann sich ein Anfänger daran erinnern, dass all diese Syntax einfacher ist, als sich nur an $ PSVersionTable zu erinnern
Joseph Gabriel

1
Leute, Get-Variable funktioniert gut alleine (wenn alles, was Sie brauchen, nur um die Version zu bekommen), Piping gibt es nur einen Witz :) Ich erinnere mich auch nicht an Piping-Syntax.
Roman Pokrovskij

7

Um zu überprüfen, ob PowerShell installiert ist, verwenden Sie:

HKLM\Software\Microsoft\PowerShell\1 Install ( = 1 )

Um zu überprüfen, ob RC2 oder RTM installiert ist, verwenden Sie:

HKLM\Software\Microsoft\PowerShell\1 PID (=89393-100-0001260-00301) -- For RC2
HKLM\Software\Microsoft\PowerShell\1 PID (=89393-100-0001260-04309) -- For RTM

Quelle: diese Website .


7

Da die hilfreichste Antwort nicht auf den vorhandenen Teil einging, dachte ich, ich würde ihn über eine schnelle und schmutzige Lösung aufgreifen. Es stützt sich auf Powershell auf dem Weg zu sein Umgebungsvariable , die wahrscheinlich ist , was Sie wollen. (Hutspitze zur obersten Antwort, da ich das nicht wusste.) Fügen Sie dies in eine Textdatei ein und benennen Sie es

Testen Sie Powershell Version.cmd

o.ä.

@echo off
echo Checking powershell version...
del "%temp%\PSVers.txt" 2>nul
powershell -command "[string]$PSVersionTable.PSVersion.Major +'.'+ [string]$PSVersionTable.PSVersion.Minor | Out-File ([string](cat env:\temp) + '\PSVers.txt')" 2>nul
if errorlevel 1 (
 echo Powershell is not installed. Please install it from download.Microsoft.com; thanks.
) else (
 echo You have installed Powershell version:
 type "%temp%\PSVers.txt"
 del "%temp%\PSVers.txt" 2>nul
)
timeout 15

4

Ich musste die Version von PowerShell überprüfen und dann den entsprechenden Code ausführen. Einige unserer Server führen Version 5 und andere Version 4 aus. Dies bedeutet, dass einige Funktionen, wie z. B. Komprimieren, möglicherweise verfügbar sind oder nicht.

Das ist meine Lösung:

if ($PSVersionTable.PSVersion.Major -eq 5) {
    #Execute code available in PowerShell 5, like Compress
    Write-Host "You are running PowerShell version 5"
}
else {
    #Use a different process
    Write-Host "This is version $PSVersionTable.PSVersion.Major"
}

3

Das folgende Cmdlet gibt die PowerShell-Version zurück.

$PSVersionTable.PSVersion.Major

2
$PSVersionTableist eine automatische Variable; ein Objekt. Es ist kein Cmdlet.
Maximilian Burszley

1

Dies ist das Top-Suchergebnis für "Batch-Datei erhält Powershell-Version". Daher möchte ich ein grundlegendes Beispiel dafür geben, wie ein bedingter Fluss in einer Batch-Datei abhängig von der Powershell-Version ausgeführt wird

Allgemeines Beispiel

powershell "exit $PSVersionTable.PSVersion.Major"
if %errorlevel% GEQ 5 (
    echo Do some fancy stuff that only powershell v5 or higher supports
) else (
    echo Functionality not support by current powershell version.
)

Beispiel aus der realen Welt

powershell "exit $PSVersionTable.PSVersion.Major"
if %errorlevel% GEQ 5 (
    rem Unzip archive automatically
    powershell Expand-Archive Compressed.zip
) else (
    rem Make the user unzip, because lazy
    echo Please unzip Compressed.zip prior to continuing...
    pause
)

0

Sie können den Befehl "host" auch über die PowerShell-Befehlszeile aufrufen. Es sollte Ihnen den Wert der $hostVariablen geben.


3
Das ist halb falsch. hostbeschließt zu Get-Host. Unabhängig davon ist es kein zuverlässiger Weg, um die Version zu erhalten.
Maximilian Burszley

-1

Erweitern der Antwort mit einem ausgewählten Operator:

Get-Host | select {$_.Version}

7
Die akzeptierte Antwort lautet "... $ Host.Version und (Get-Host) .Version sind nicht zuverlässig - sie geben nur die Version des Hosts wieder, nicht die Engine" .
Peter Mortensen

@ PeterMortensen sieht aus wie meine Antwort vor der akzeptierten Antwort war
HaBo

2
@ HaBo Was schaust du dir an? Die akzeptierte Antwort ist von 2009.
TylerH

@ TylerH na und? Ich folge Ihrer Frage nicht. Meine Antwort besagt eindeutig, dass es eine Erweiterung der akzeptierten Antwort ist. Es ist eine vereinfachte Version.
HaBo

2
@HaBo Ihr vorheriger Kommentar lautet, als würden Sie Ihre Antwort damit begründen, dass sie vor der akzeptierten Antwort veröffentlicht wurde, was überhaupt nicht der Fall ist. Ihre Antwort wurde 7 Jahre nach der akzeptierten Antwort und 6 Jahre nach der Antwort veröffentlicht, die Ihre Antwort tatsächlich "verlängert". Apropos, Ihre Antwort sagt nicht eindeutig, dass es sich um eine Erweiterung der akzeptierten Antwort handelt (die nicht einmal verwendet wird Get-Host).
TylerH
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.