Powershell: Feature Request Support Versioning für Standalone-Funktionen

Erstellt am 23. Jan. 2020  ·  60Kommentare  ·  Quelle: PowerShell/PowerShell

Zusammenfassung der neuen Funktion/Erweiterung

Wenn Sie Get-Command verwenden, werden Versionsinformationen für einen Befehl nur angezeigt, wenn er Teil eines Moduls mit einem Manifest ist. Und selbst dann denke ich, dass die Version wirklich für das Modul ist. Es sollte eine Möglichkeit geben, die Versionierung auf Funktionsebene zu unterstützen, insbesondere für eigenständige Dateien. Ich habe möglicherweise einen einzelnen Funktionsbefehl in einer PS1-Datei. Ich freue mich, die Quelle zu dotieren und den Befehl auszuführen. Aber ich möchte eine Versionsnummer sehen, wenn ich Get-Command verwende.

Vorgeschlagene technische Implementierungsdetails (optional)

Die System.Management.Automation.FunctionInfo-Klasse verfügt über die erforderlichen Eigenschaften, sie sind jedoch schreibgeschützt. Es wäre schön, eine Funktion zu haben, die den PScriptInfo-Metadaten entspricht, die mit PowerShellGet und veröffentlichten Skripts verwendet werden. Lassen Sie mich einen Metadatenabschnitt haben, den PowerShell verarbeitet und verwendet, wenn die Funktion in PowerShell importiert wird.

Committee-Reviewed Issue-Enhancement Resolution-Answered

Hilfreichster Kommentar

Es geht nicht darum, Funktionen auszuführen oder zu verteilen. Alles, was ich möchte, ist ein Mechanismus, der eine Möglichkeit bietet, Versionsinformationen zu verfolgen und zu ermitteln, sodass ich, wenn ich Get-Command oder vielleicht einen neuen Befehl wie Get-Function ausführe, einige Metadaten zu der Funktion sehen kann. Ich habe einige Ideen, die ich versuchen könnte, mithilfe von PowerShell-Skripting Prototypen zu erstellen.

Alle 60 Kommentare

Bitte fügen Sie Informationen hinzu, wie Sie die PowerShell-Sprache verbessern möchten, um die Version hinzuzufügen. Im Cmdletbinding-Attribut?

Mein Gedanke war, etwas wie New-ScriptFileInfo zu tun, das einen Kommentarheader wie folgt generiert:

<#PSScriptInfo

.VERSION 1.0

.GUID 66c837b7-6478-4571-9dec-0621e13df4c3

.AUTHOR Jeff

.COMPANYNAME

.COPYRIGHT 2020

.TAGS

.LICENSEURI

.PROJECTURI

.ICONURI

.EXTERNALMODULEDEPENDENCIES 

.REQUIREDSCRIPTS

.EXTERNALSCRIPTDEPENDENCIES

.RELEASENOTES


.PRIVATEDATA

#>

<# 

.DESCRIPTION 
 This is a cool function 

#> 
Param()

Machen Sie es zu PSFunctionInfo und lassen Sie es von Get-Command analysieren. Oder wie PowerShell #requires parsen kann, lassen Sie es #version parsen. Schwierig wird es, wenn Sie mehrere Funktionen in derselben ps1-Datei haben, also müsste alles, was ich als Funktionsautor tun würde, in die Funktion eingeschlossen werden. Dies kann ein geparster Kommentarblock, eine neue Option cmdletbinding() oder vielleicht ein ganz neues Attribut sein.

Function Get-Awesomeness {

 [cmdletbinding()]
 [alias("awe")]
 [outputtype("psobject")]
 [version("1.1.0")]

 Param ()

 ...
}

Ich sehe keinen Wert aus der Funktion. Wir können auf PowerShellGet veröffentlichen und PowerShell-Skripte nur als Module verteilen, dies können wir nicht für Dateien tun. Können Sie einen Business Case/Workflow beschreiben?

Es gibt viele Leute, die PowerShell-Lösungen erstellen, die nie in der Galerie veröffentlicht werden. Sie werden intern verwendet, beispielsweise in einer Unternehmensumgebung. Und nicht alles ist in ein Modul verpackt. Ich arbeite möglicherweise in einer Unternehmensumgebung und habe eine eigenständige Skriptdatei mit einer Funktion. Ich möchte die Möglichkeit haben, die Version für diese Funktion zu verfolgen. Wenn ich Get-Command Get-CompanyFoo ausführe, muss ich eine Versionsnummer sehen können. Auch in einem Modul haben alle exportierten Funktionen dieselbe Versionsnummer. Ich hätte gerne eine Möglichkeit, Versionsinformationen pro Funktion zu verfolgen. Und das natürlich ohne auf das Auslesen des Quellcodes angewiesen zu sein. Wenn ein Helpdesk-Techniker eine meiner Funktionen verwendet, muss er PowerShell verwenden können, um die Befehlsversion zu ermitteln.

Sicherlich braucht das nicht jede Funktion, auch nicht die in einem Modul. Ich habe kein Problem mit einer Funktion in einem Modul, die die Modulversion verwendet, wenn keine befehlsspezifische Version erkannt wird.

@jdhitsolutions Danke!

Ich sehe in Ihrem Szenario zwei Komponenten - (1) ein Versionsverfolgungssystem, (2) ein Verteilungssystem.
Der erste könnte GIT sein (andere?).
Es ist nicht klar, wie Sie Skriptdateien verteilen.

(Ich versuche zu verstehen, wo das angeforderte Attribut richtig ist.)

Ich hinterlasse regelmäßig Funktionen bei Kunden, die zum Zeitpunkt der letzten Verwendung bei diesem bestimmten Kunden aktuell sind. Eine, die ich heute bei einem Kunden verwendet habe, fällt mir ein - getWUlog. Es weiß, wie man mit WinRM und psexec eine Verbindung zu einem Remote-System herstellt (es prüft, ob 139 oder 5985 geöffnet sind) und das WindowsUpdate-Protokoll von diesem Computer abrufen, auf dem lokalen Computer abrufen und den Editor öffnen.

Eine andere ist getFrameworkVersion. Tut genau das - sucht nach der .NET Framework-Version, die auf einem bestimmten Computer installiert ist, entweder über CIM oder den Remote-Registrierungsdienst (erneut - überprüft die Ports, um herauszufinden, was zu tun ist), meldet diese und meldet, welche Versionen blockiert sind, wenn überhaupt.

Dies sind eigenständige Funktionen. Nicht Teil eines Moduls. Aber sie wurden in den letzten Jahren regelmäßig aktualisiert.

Es wäre toll, jedem von ihnen eine Version beizufügen. Im Moment habe ich nur ein "letztes Änderungsdatum" oben in der Quelle. Nicht so nützlich...

Die Verteilung ist meiner Meinung nach für diese Diskussion irrelevant. Und ja, Git spielt eine Rolle, ist aber nicht das Problem. Wenn ich in PowerShell bin und eine eigenständige Funktion verwende. Wenn ich Get-Command Get-Foo ausführe, möchte ich die Versionsnummer der Funktion sehen. So einfach ist das. Es spielt keine Rolle, wie die Funktion verteilt wurde. Geben Sie mir eine Möglichkeit, Metadaten in die Funktion einzufügen.

Und um es ganz klar zu sagen, ich möchte weder einen Benutzer noch mich selbst dazu zwingen, die Quelle aufzuspüren und nach Kommentaren oder Notizen zu suchen.

Ich schreibe/nutze definitiv einige eigenständige Funktionen, aber die meisten sind in Modulen. Und die meisten von denen sind zufällig Treibgut - Tools , die als Standalone - Funktionen verwendet werden können. Ich füge semantische Versionen und Änderungsprotokolle immer in .NOTES im Kommentarblock und ein [version]$Version in den Anfangsblock ein, weil ich verfolgen möchte, welche Änderungen ich an einer bestimmten Funktion vorgenommen habe, nicht nur zum Modul (das ich inkrementiere, wenn ich Änderungen an den inneren Funktionen vornehme). Etwas wie [version()] oder [cmdletbinding(Version='01.00.0000')] wäre spektakulär; Ich mag es besser als .VERSION, weil ich weiß, dass viele Leute mehrere Funktionen in eine psm1-Datei packen (obwohl ich das nicht tue).
Ich benutze übrigens auch git, aber ich verbinde nicht jedes Mal, wenn ich eine Änderung an einer einzelnen Funktion vornehme; Ich bündele sie und verbinde sie, wenn ich das Modul ändere, normalerweise mit der Modulversion als Commit-Nachricht. Ja, ja, ich weiß, ich bin komisch.

Wenn das Skript in $env:PATH , wird es für Get-Command angezeigt. Daher erscheint es sinnvoll, die vorhandenen ScriptFileInfo-Metadaten den ExternalScriptInfo-Mitgliedern zuzuordnen, die die Version enthalten.

Seien Sie vorsichtig mit dieser Annahme, Steve. Ich habe möglicherweise eine einzelne PS1-Datei mit mehreren Funktionen. Ich möchte nicht darauf vertrauen, dass Get-Command die Skriptdatei finden kann. Verdammt, ich möchte vielleicht eine versionierte Funktion in einem PowerShell-Profilskript definieren.

Ich habe definitiv versionierte Funktionen in meinem Profilskript.

Wir haben bereits den Typ System.Management.Automation.FunctionInfo mit einer Version-Eigenschaft. Wir brauchen eine Möglichkeit, damit beim Laden der Funktion die Versionseigenschaft aus den Metadaten in der Funktion aufgefüllt wird.

Danke an alle für das tolle Feedback! Ich habe noch einige Fragen. Welches Verhalten erwarten Sie, wenn PowerShell einige Funktionen mit demselben Namen findet? Funktion mit höherer Version ausführen? Sollen wir Bereiche berücksichtigen (Sie laden im aktuellen Bereich die alte Funktion - sollten wir mehr neue Funktion aus dem globalen Bereich aufrufen)? Oder wollen wir nur Informationsattribute haben?

Es geht nicht darum, Funktionen auszuführen oder zu verteilen. Alles, was ich möchte, ist ein Mechanismus, der eine Möglichkeit bietet, Versionsinformationen zu verfolgen und zu ermitteln, sodass ich, wenn ich Get-Command oder vielleicht einen neuen Befehl wie Get-Function ausführe, einige Metadaten zu der Funktion sehen kann. Ich habe einige Ideen, die ich versuchen könnte, mithilfe von PowerShell-Skripting Prototypen zu erstellen.

Danke an alle für das tolle Feedback! Ich habe noch einige Fragen. Welches Verhalten erwarten Sie, wenn PowerShell einige Funktionen mit demselben Namen findet? Funktion mit höherer Version ausführen? Sollen wir Bereiche berücksichtigen (Sie laden im aktuellen Bereich die alte Funktion - sollten wir mehr neue Funktion aus dem globalen Bereich aufrufen)? Oder wollen wir nur Informationsattribute haben?

Ich glaube nicht, dass irgendjemand eine Änderung der Art und Weise, wie PS Funktionen ausführt, vorgeschlagen hat. Wir wollen nur eine Version davon erstellen. Informativ und eine Möglichkeit, diese zu befragen.

Danke! Nächste Frage habe ich. Eine Datei mit einigen Funktionen kann ein gemeinsames Versionsattribut für alle Funktionen in der Datei haben. Sollten wir dies berücksichtigen?

Ich habe einige Ideen, die ich versuchen könnte, mithilfe von PowerShell-Skripting Prototypen zu erstellen.

Sie könnten die Ideen im Wesentlichen teilen.

Das ist mein Plan.

Soll es die klassische Version oder SymVer 2.0 sein?

Ich bin immer mehr davon überzeugt, dass die Versionierung von Funktionen eine gute Sache ist.

Um die neueste Frage von @iSazonov zu beantworten: Wenn wir sie haben sollen, warum nicht SymVer verwenden?

Und in Bezug auf eine Datei mit Funktionen - ich würde argumentieren, dass das Attribut pro Funktion ohne Attribute pro Datei ist. Ähnlich wie das heutige CMDLETBinding funktioniert.

Prototyp wird eingezogen ##11686

Sie können ein Artefakt aus dem PR herunterladen und mit neuen Attributen spielen.

Süss.

Denken Sie darüber nach - warum erweitern Sie nicht das PSVersionAttribute, um die Version des Skripts einzuschließen. Wenn wir Module und (hoffentlich jetzt!) Funktionen versionieren, warum dann nicht Skripte?

Das PSVersionAttribute könnte auch als Standardwert für im Skript definierte Funktionen dienen.

Und bevor jemand fragt... Kann die Ausführung von Funktionen versioniert werden?

Wir könnten mehrere Versionen einer Funktion laden, standardmäßig die neueste ausführen, aber einen gemeinsamen Parameter -PSFunctionVersion haben, der angibt, welche spezifische Version ausgeführt werden soll.
Zweifellos gibt es mehr Alternativen - aber sollten wir eine versionierte Funktionsausführung anbieten?

Wenn es ein Attribut ist, können Sie es immer einfach wiederverwenden, ähnlich wie [CmdletBinding()] sowohl auf Funktionen als auch auf Skripte angewendet werden kann, Sie können immer nur [PSVersion()] sowohl für Funktionen als auch für Skripte verwenden. Das sieht nach einem interessanten Ansatz aus. 🙂

In Modulen, in denen wir größtenteils bereits versionierten Code haben, sehe ich so etwas nicht viel Verwendung, aber für eigenständige Skripte und Funktionen könnte dies sehr interessant sein 🙂

Es geht nicht darum, Funktionen auszuführen oder zu verteilen. Alles, was ich möchte, ist ein Mechanismus, der eine Möglichkeit bietet, Versionsinformationen zu verfolgen und zu ermitteln, sodass ich, wenn ich Get-Command oder vielleicht einen neuen Befehl wie Get-Function ausführe, einige Metadaten zu der Funktion sehen kann. Ich habe einige Ideen, die ich versuchen könnte, mithilfe von PowerShell-Skripting Prototypen zu erstellen.

Wenn wir die Versionsverwaltung von Funktionen hinzufügen möchten, warum sollten wir sie dann auf die reine Dokumentation beschränken? Wenn ich Funktionsversionen angeben und abfragen kann, wäre es dann nicht sinnvoll, die Ausführung basierend auf der Versionsnummer zuzulassen?

Entweder eine Möglichkeit, mehrere Versionen einer Funktion zu laden und die auszuführende auszuwählen, oder es dem Benutzer zu ermöglichen, zwischen verschiedenen Versionen auszuwählen, die in die mit gcm angezeigte Funktionsliste geladen und dann ausgeführt werden.

Hier ist also ein Proof of Concept, den ich basierend auf den ScriptFileInfo-Befehlen erstellt habe:
https://gist.github.com/jdhitsolutions/65070cd51b5cfb572bc6375f67bcbc3d

Was ich wirklich versuche zu modellieren oder zu prototypieren, ist die Erfahrung. Ich möchte die Daten lieber mit Get-Command verfügbar machen, da es bereits einen entsprechenden Typ gibt.

image

Und eine Mischung von Dateien erhalten.
image

Wenn eine Funktion zu einem Modul gehört, werde ich mich nicht um die Befehlsversionierung kümmern. Das sollte das Modul übernehmen.

Kern
Ein Machbarkeitsnachweis zum Hinzufügen und Abrufen von PowerShell-Metadateninformationen - PSFunctionInfo.format.ps1xml

Netter Jeff!

Wie gehen wir also mit mehreren Versionen derselben Funktion um?
Wie lädt man explizit eine bestimmte Funktionsversion?
Wie führt man eine bestimmte Version einer Funktion explizit aus?

@doctordns Sie sind dafür verantwortlich, herauszufinden, was ausgeführt werden soll, und mit mehreren Versionen umzugehen. Mein Prototypcode listet einfach Elemente in der FunctIon: Psdrive auf und zeigt Metadateninformationen an. Soweit ich weiß, können Sie im psdrive keine doppelten Funktionen haben. Mein Ziel war es, wenn ich eine Standalone-Funktion geladen habe, möchte ich in der Lage sein, Versions- und möglicherweise andere Metadateninformationen abzurufen.

Obwohl ich denke, dass es wunderbar wäre, wenn PowerShell die _eingebetteten_ PSScriptInfo-Metadaten für _Skripte_ unterstützt ... bitte tun Sie dies nicht auf der _Funktions-Ebene.

Versionen sind nur sinnvoll, wenn man etwas dagegen tun kann

PowerShell _meldet_ derzeit die Version über Befehle, aber die tatsächliche Version stammt aus dem _Modul_. Separate Versionen für jede Funktion zu haben wäre nicht hilfreich, es wäre nur verwirrend. Unabhängig davon, wie Sie Ihren Code verteilen, verteilen Sie keine Unterdatei-"Hunks" und der Benutzer kann keine einzelne Funktion (oder etwas anderes als eine vollständige Datei) laden - es macht also keinen Sinn, sie zu versionieren.

Ich denke, wir brauchen Versionen für Module und Skripte. Funktionen sollten ihre Version von dem _module_ erben, das sie enthält. Skripte benötigen eine eigene Version.

Für das Protokoll:

Wenn Sie eine .ps1-Datei mit mehreren Funktionen haben, müssen Sie die Erweiterung ändern. Wenn Sie dies nicht tun, haben Benutzer sowieso keine Möglichkeit, diese Funktionen zu entdecken, sodass die Versionierung keine Rolle spielt. Wir sollten jeden aktiv davon abhalten, _Funktionen_ in etwas anderem als einem Modul zu verteilen. 🤨

@Jaykul Ich stimme zu, dass die geliefert wird, was das Ziel sein sollte. Es gibt jedoch viele Benutzer, die eigenständige Funktionen verwenden. Vielleicht in einem Profil geladen oder per Dot Source, um einen bestimmten Bedarf zu erfüllen. Nicht alles, was ich tue, muss geladen und in ein Modul eingebaut werden. Es sind diese Nicht-Modul-Funktionen, die ich verwalten möchte. Ich möchte eine Möglichkeit haben, Versions- und andere Metadateninformationen zu erfassen, genau wie wir es für Befehle tun, die aus einem Modul geladen werden. Vielleicht ist die Antwort ein neuer Befehl wie mein Prototyp.

@Jaykul Ich denke, dass mehrere von uns bereits gesagt haben, dass es für uns tatsächlich nützlich wäre und dass wir tatsächlich einzelne Funktionen verteilen.

IMO, nicht alles braucht ein Modul.

Die vorgeschlagene Funktion ist für Sie möglicherweise nicht von Nutzen. Und das ist in Ordnung. Aber es ist für andere von uns.

Ich mag die Idee der Funktionsversionierung. Aber wenn wir eine Lösung machen, sollte es mehr als eine kleine Dokumentation sein, die Sie in Kommentaren tun könnten. Ohne die Möglichkeit, das Laden verschiedener Versionen usw. zu steuern, können wir auf diese Funktion derzeit möglicherweise verzichten.

Ich schlage vor, dass wir diese Idee für 7.0 fallen lassen. Wir sind ZU nah an RTM, um neue Funktionen in den Mix einzubringen. Ich habe schlechte Erinnerungen an NT 5 Tage!! Wenn wir dies auf 7.1 zurückschieben können, dann lassen Sie uns ein ausführlicheres Gespräch darüber führen, wie es vollständig implementiert werden kann. Der Versuch, dies nur in letzter Minute zu verdrängen, ist ein sicherer Weg, Enttäuschungen zu verursachen.

In diesem Fall handelt es sich um einen 7.1-Zusatz. Ich denke, das Problem, die richtige Version zu laden, liegt beim Benutzer. Auch hier frage ich nur nach einer Möglichkeit, Versionsinformationen von einer geladenen eigenständigen Funktion abzurufen, ohne durch die Quelle graben zu müssen.

Ich stimme 7.1 zu.

Gleichzeitig èich kenne die Benutzer und wette, dass eine Dokumentationslösung nur Anfragen nach versionierten Laufzeitfeatures generiert. Ich möchte, dass wir eine vollständige und elegante sowie ausgereifte Lösung in Betracht ziehen. .

Wir haben bereits eine Lösung für Standalone-Funktionen - die zuletzt geladene gewinnt. :-)

Ohne die Möglichkeit, das Laden verschiedener Versionen usw. zu steuern, ist dies eine Funktion, auf die wir möglicherweise vorerst verzichten können.

Dies würde uns zwingen, die Version der Funktion bei jedem Aufruf zu überprüfen. Dies ist aus Leistungsgründen völlig inakzeptabel. Das Modul ist der beste Kompromiss - die Versionsprüfung wird einmal beim Laden des Moduls durchgeführt.

@SteveL-MSFT Ich glaube, es ist bereit für den Abschluss des PowerShell-Komitees. Prototyp #11686.

Es scheint alle übereinstimmend zu sein, dass eine Version für Skripte in der Engine nützlich ist.
Version für Funktionen ist in Frage, da Modulkonzeption vorhanden ist.

Eine allgemeine Einschränkung ist, dass wir nur Versionen für geladene Skripte und Funktionen sehen können und nicht das tun können, was import-module tut - benötigte Version laden, aber get-module hat auch keine expliziten Versionsparameter.

Denken Sie nicht zu viel darüber nach oder machen Sie es komplizierter, als es sein muss. Mit Modulen ausgelieferte Funktionen gehören zum Modul. Punkt. Das sollte die empfohlene Best Practice sein. Allerdings wird nicht jede Funktion, die in der Produktion verwendet werden könnte, mit einem Modul bereitgestellt. Es ist mir eigentlich egal, wie es eingesetzt wird. Ich sage nur, dass ich eine Möglichkeit haben möchte, eine geladene Funktion in Function: PSDrive anzuzeigen und eine Versionsnummer und vielleicht einige andere Metadateninformationen anzuzeigen. Ich möchte weder mich noch einen Endbenutzer dazu zwingen, den Quellcode oder Ordner aufzuspüren, um Versionsinformationen zu finden.

Ich hatte gehofft, Get-Command wäre das Werkzeug zum Sammeln dieser Informationen, aber vielleicht muss dies in etwas völlig separates für die eigenständige Funktionsverwaltung ausgegliedert werden.

Und vielleicht ist die Antwort, dass dieses Problem am besten der Community überlassen wird. In diesem Fall denke ich, dass ich einen guten Ausgangspunkt für eine Lösung habe.

Die ehrliche Wahrheit ist, dass Dot-Sourcing-Funktionen nicht der richtige Weg sind und all die Jahre nicht empfohlen werden sollten, als das Modulsystem in v2 auf den Markt kam. Das einzige Mal, dass es für die Verwendung aus der Ferne sinnvoll war, war in v1.

Wie wir jetzt alle wissen, sollten alle Funktionen realistischerweise innerhalb eines Moduls platziert werden, auch diejenigen, die Sie als Teil Ihres Profils laden (das Sie das Modul mit diesen Funktionen laden sollten) oder zur einfacheren Wartung als Teil eines größeren Skripts verwenden. oder sogar die einzelnen Funktionen, die Sie in xyz-Skripten verwenden müssen.

Ich kann nur sehen, dass diese Änderung denjenigen, die zur Sprache kommen, mehr Verwirrung als Nutzen bringen würde, indem das vorgeschlagene [Version] Attribut zu Funktionsdefinitionen hinzugefügt wird, da viele denken, dass sie Modul- und Funktionsversionen festlegen müssen, wenn sie dies tun Dinge richtig zu machen und tatsächlich Module aus wiederverwendbarem Code zu erstellen.

Ja, das bedeutet, dass Sie eine psd1 und eine psm1 haben müssen, aber 2 Dateien für eine ordnungsgemäße Auffindbarkeit und Wartbarkeit sind keine große Aufgabe, um sie wirklich zu verwalten

Wie Sie vielleicht sehen, bin ich persönlich mit dieser Änderung nicht einverstanden und denke, es gibt bessere Dinge, auf die man sich stattdessen konzentrieren sollte

Ja, das bedeutet, dass Sie eine psd1 und eine psm1 haben müssen, aber 2 Dateien für eine ordnungsgemäße Auffindbarkeit und Wartbarkeit sind keine große Aufgabe, um sie wirklich zu verwalten

Ja, es ist eine riesige Frage. Der Versuch, Admin-Skripter zu Entwicklern zu machen, erhöht die Eintrittsbarriere erheblich.

Zu sagen "Oh, Sie müssen das hier kopieren und das dorthin kopieren und dann importieren" ist viel komplizierter und viel fehleranfälliger als zu sagen "Kopieren und fügen Sie dies in eine Datei namens run.ps1 ein und geben Sie dann ,\run . ein .ps1".

Dies ist eine geringfügige Änderung, von der Gelegenheits-/Admin-Skripter weit mehr profitieren als ternäre Operatoren oder Null-Koaleszenz (was ich immer noch nicht verstehe) oder viele andere kürzlich vorgenommene Änderungen, die für diejenigen unter Ihnen, die Entwickler sind, vorgenommen wurden. Wie bereits gesagt, kann ich zu Funktionsversionen sagen: Wenn es Ihnen nicht gefällt, verwenden Sie es nicht.

@SteveL-MSFT Ich glaube, das PowerShell-Komitee könnte die Anfrage zur Unterstützung von Versionen für Skripte und eigenständige Funktionen prüfen. Prototyp ist in #11686.

Die ehrliche Wahrheit ist, dass Dot-Sourcing-Funktionen nicht der richtige Weg sind,

Aber die Leute tun es, und es ist sowieso nicht der einzige Anwendungsfall für diese Anfrage.

und sollte all die Jahre nicht empfohlen werden, als das Modulsystem in v2 auf den Markt kam. Das einzige Mal, dass es für die Verwendung aus der Ferne sinnvoll war, war in v1.

Wie wir jetzt alle wissen, sollten alle Funktionen realistischerweise innerhalb eines Moduls platziert werden, auch diejenigen, die Sie als Teil Ihres Profils laden (das Sie das Modul mit diesen Funktionen laden sollten) oder zur einfacheren Wartung als Teil eines größeren Skripts verwenden. oder sogar die einzelnen Funktionen, die Sie in xyz-Skripten verwenden müssen.

Ich kann nur sehen, dass diese Änderung denjenigen, die zur Sprache kommen, mehr Verwirrung als Nutzen bringen würde, indem das vorgeschlagene [Version] Attribut zu Funktionsdefinitionen hinzugefügt wird, da viele denken, dass sie Modul- und Funktionsversionen festlegen müssen, wenn sie dies tun Dinge richtig zu machen und tatsächlich Module aus wiederverwendbarem Code zu erstellen.

Ja, das bedeutet, dass Sie eine psd1 und eine psm1 haben müssen, aber 2 Dateien für eine ordnungsgemäße Auffindbarkeit und Wartbarkeit sind keine große Aufgabe, um sie wirklich zu verwalten

Ja, aber das ist nicht relevant. Niemand argumentiert, dass wir Module nicht versionieren sollten. ;-)

Wie Sie vielleicht sehen, stimme ich dieser Änderung nicht zu und denke, dass es bessere Dinge gibt, auf die man sich stattdessen konzentrieren kann

Sie müssten es nicht verwenden. Sie sind auch nicht gezwungen, [CmdletBinding()] oder Parametersätze zu verwenden.
Befehle und Cmdlets haben Versionen.
Wenn eine Funktion selbst eine Version hat, _unabhängig davon, ob sich die Funktion in einem Modul befindet oder nicht_, ist dies nur ein kleiner, aber nützlicher Dokumentationspunkt. Ich habe zahlreiche Module mit unterschiedlichen und nicht verwandten Werkzeugen erstellt, die ihre eigenen individuellen Module nicht rechtfertigen. Wenn mein Modul MiscStuff 1.1.0002 ist, ist das großartig für den Verteilungsteil; Ich benutze das. Wenn es dreißig Funktionen enthält und ich schnell feststellen möchte, ob ich Do-Thing 7.9.0 und es mit einem Eintrag in meinem Changelog korrelieren möchte (was ich tue!), möchte ich eine formale Methode dafür tun, was von denen, die es nicht wollen, in keiner Weise verlangt wird.

@PowerShell/powershell-committee hat dies überprüft. Wir glauben, dass die richtige Lösung für die Versionierung von Skriptfunktionen darin besteht, sie in ein Modul zu packen. Es ist auch nicht klar, wie das erwartete Verhalten aussehen würde, wenn sich die Skriptfunktion innerhalb eines Moduls befindet, aber ein eigenes Versionsattribut hat. Dann gibt es Bedenken hinsichtlich anderer Teile von PowerShell, PowerShellGet und PSGallery, die aktualisiert werden müssten, um dieses neue Attribut zu berücksichtigen. Wenn Sie eine einzelne Skriptdatei im Vergleich zu einem Ordner (Modul) weitergeben möchten, ist es besser, in die Möglichkeit zu investieren, ein zip/nupkg-Modul direkt zu

Als Admin-Scripter und nicht als Entwickler glaube ich nicht, dass #7259 und diese Anfrage (#11667) etwas miteinander zu tun haben.

Als Admin-Scripter WERDE ich NICHT lernen, wie man Module verwendet. Es ist für mich nicht relevant. Es bietet mir KEINEN WERT. Für ENTWICKLER ist das ein Overhead. Module sind ein Nicht-Starter. (Nicht nur für mich, sondern für die meisten Admin-Skripter.)

Für Admin-Skripter und nicht Entwickler – wie schlägt das Komitee vor, dass die Versionierung für Funktionen/Filter durchgeführt wird?

Um nicht widersprüchlich zu sein, aber... die Versionierung selbst ist im Großen und Ganzen ein Entwicklerkonzept. Ich bin mir nicht sicher, warum Sie ausgerechnet hier diese Grenze ziehen wollen. 😕

Weil ich Dutzende von eigenständigen Funktionen und Skripten veröffentlicht habe. Ohne Module. Ziemlich sicher, dass dies oben in früheren Kommentaren von mir und mehreren anderen beliebten Bloggern/Verlegern behandelt wurde.

Ich glaube nicht, dass #7259 und diese Anfrage (#11667) etwas miteinander zu tun haben.

Ja, ich verstehe die Verbindung auch nicht wirklich, um ehrlich zu sein.

ICH WERDE NICHT lernen, wie man Module verwendet.

FWIW ändern Sie einfach die Erweiterung in psm1 und führen (optional) New-ModuleManifest . Es ist nicht viel dabei.

Es ist für mich nicht relevant. Es bietet mir KEINEN WERT.

Wenn Sie etwas veröffentlichen, damit andere es konsumieren können, bietet es definitiv einen Mehrwert. Die Art und Weise, wie Bereiche für Module funktionieren, macht es viel schwieriger, auf den globalen Sitzungsstatus einer Person zu treten und umgekehrt. Das macht Ihre Funktion deutlich widerstandsfähiger gegenüber unerwarteten Unterschieden in der Umgebung.

Es ist auch viel einfacher zu konsumieren. Wenn Sie eine Funktion als Skript freigeben, müssen die Leute eine Dot-Source-Funktion verwenden, sie müssen wissen, wo sie sich befindet, sie Dot-Source und dann den Befehl verwenden. Wenn Sie es als Modul veröffentlichen, können die Leute es einfach im Voraus bereitstellen und jederzeit aufrufen.

Wie schlägt der Ausschuss vor, dass die Versionierung für Funktionen/Filter durchgeführt wird?

Wenn die Versionierung für einzelne Funktionen implementiert wäre, würden Sie erwarten, dass deren Version abfragbar ist?

Wenn ja, können Sie ein wenig näher erläutern, welches Szenario Sie erwarten würden, dass der Benutzer es abfragt? Würden Sie erwarten, dass es in andere Systeme wie #requires Tags einspielt?

Wenn es sich nur um Metadaten handelt, die in der Quelle sichtbar sind, können Sie sie einfach in den Abschnitt NOTES der kommentarbasierten Hilfe einfügen.

Basierend auf den Schlussfolgerungen des PowerShell-Komitees schließe ich das Problem (Stoppverfolgung), aber es steht Ihnen frei, die Diskussion fortzusetzen.

Ja, ich verwende heute den Abschnitt NOTES und eine $pVersion/$pName. Ich vermute die meisten von uns mit der Notwendigkeit, das zu tun.

Als ich "Ich werde nicht" schrieb, sprach ich von der generischen Person, nicht speziell von mir (obwohl ich in diese Kategorie falle).

und ein $pVersion/$pName

Was machst du mit denen? Haben Sie ein Beispiel für eine lose Funktion, die Sie veröffentlicht haben? Das kann beim Verständnis des Anwendungsfalls helfen.

Als ich "Ich werde nicht" schrieb, sprach ich von der generischen Person, nicht speziell von mir (obwohl ich in diese Kategorie falle).

Ja, es gibt definitiv Leute, die sich weigern, etwas über Module zu lernen. Ich habe viele solcher Leute gekannt und kenne sie derzeit (und wurden vor ein paar Jahren als Leute bezeichnet), keine Argumente dafür, dass sie existieren. Das heißt, die Überschneidung zwischen diesen Leuten und denen, die 1. sich für Versionierung interessieren und 2. den Wunsch haben, ihre Arbeit zu veröffentlichen, ist meiner Erfahrung nach fast null. Realistischerweise werden die meisten Leute, die die Kästchen 1 und 2 ankreuzen, die ~ 10 Minuten brauchen, um vor der Veröffentlichung schnell zu googeln, wie man ein Modul einbindet. Oder häufiger, sie kümmern sich nicht um die Versionierung und sie knallen es einfach in einen Kern oder einen Blogbeitrag.

und ein $pVersion/$pName

Was machst du mit denen? Haben Sie ein Beispiel für eine lose Funktion, die Sie veröffentlicht haben? Das kann beim Verständnis des Anwendungsfalls helfen.

Als ich "Ich werde nicht" schrieb, sprach ich von der generischen Person, nicht speziell von mir (obwohl ich in diese Kategorie falle).

Ja, es gibt definitiv Leute, die sich weigern, etwas über Module zu lernen. Ich habe viele solcher Leute gekannt und kenne sie derzeit (und wurden vor ein paar Jahren als Leute bezeichnet), keine Argumente dafür, dass sie existieren. Allerdings ist die Überschneidung zwischen diesen Leuten und denen, die 1. sich für Versionierung interessieren und 2. den Wunsch haben, ihre Arbeit zu veröffentlichen, meiner Erfahrung nach _fast_ null. Realistischerweise werden die meisten Leute, die die Kästchen 1 und 2 ankreuzen, die ~ 10 Minuten brauchen, um vor der Veröffentlichung schnell zu googeln, wie man ein Modul einbindet. Oder häufiger, sie kümmern sich nicht um die Versionierung und sie knallen es einfach in einen Kern oder einen Blogbeitrag.

Ich weiß, wie man Module verwendet. Ich schreibe sie die ganze Zeit. Verdammt, diese Funktionen sind die meiste Zeit in Modulen , und ich verwende interne Versionsverwaltung, damit ich verfolgen kann, was zuletzt in einer Funktion geändert wurde, ohne in ein externes (zur Funktion) Changelog ziehen zu müssen. Ich verstehe nicht, warum .VERSION in einer Funktion eine Modulversion stören würde. Ich einfach nicht.

Ich weiß, wie man Module verwendet. Ich schreibe sie die ganze Zeit. Verdammt, diese Funktionen sind die meiste Zeit _innerhalb_ _Module_, und ich verwende interne Versionsverwaltung, damit ich verfolgen kann, was zuletzt in einer Funktion geändert wurde, ohne in ein externes (zur Funktion) Changelog ziehen zu müssen. Ich verstehe nicht, warum .VERSION in einer Funktion eine Modulversion stören würde. Ich einfach nicht.

Richtig, aber die Hauptsache ist: Was machen Sie mit diesen Metadaten? Sehen Sie sich das nur in der Quelle der Funktion an? Wenn ja, können Sie erläutern, warum der Abschnitt .NOTES dafür nicht geeignet ist?

Dieses Problem bestand auch darin, dass eine eigenständige Funktion ihre Versionsnummer in der Ausgabe von Get-Command deklarieren konnte. Eine Anforderung, ein vollständiges Änderungsprotokoll einzufügen, wäre eine ziemlich andere Implementierung und wahrscheinlich in einem eigenen Problem besser aufgehoben.

das ist leicht zu beantworten. Das bedeutet, dass ich es in einem Editor öffnen oder eine Art umständliche String-Suche durchführen muss, um die Version herauszufinden, die auf einem bestimmten Computer/einem bestimmten Speicherort auf dem Computer installiert ist. das ist nicht immer so einfach wie diese antwort. :-)

Nicht wirklich?

Das Notes-Feld wird in der Get-Help-Ausgabe angezeigt, wenn Sie es als richtige kommentarbasierte Hilfe schreiben (was Sie sowieso sein sollten).

function test {
    <#
    .NOTES
    Version: 1.5.0
    #>
    [CmdletBinding()]
    param()
}

Get-Help test -Full

# or
Get-Help test | % alertSet

Ergebnis:

PS> Get-Help test -Full
SYNTAX
    test [<CommonParameters>]


DESCRIPTION


PARAMETERS
    <CommonParameters>
        This cmdlet supports the common parameters: Verbose, Debug,
        ErrorAction, ErrorVariable, WarningAction, WarningVariable,
        OutBuffer, PipelineVariable, and OutVariable. For more information, see
        about_CommonParameters (https://go.microsoft.com/fwlink/?LinkID=113216).

INPUTS

OUTPUTS

NOTES


        Version: 1.5.1


RELATED LINKS

PS> get-help test | % alertset



    Version: 1.5.1

So? Ich bin nicht beeindruckt. Es gab auch andere, ausführlichere Möglichkeiten, ternäre Operatoren auszuführen. Und doch... wurde ein kompakterer Weg implementiert. Weil (ein Teil der) Community es wollte. Ich weiß immer noch nicht, was zum Teufel Null-Koaleszenz-Operatoren sind.

Dann bin ich mir nicht ganz sicher, was Sie wollen. Damit können Sie ganz klar das tun, wonach Sie suchen, relativ einfach. Ich sehe es nicht als sinnvoll an, dort zusätzliche Felder hinzuzufügen.

Wenn Sie dies tun, können Sie gerne eine PR eröffnen und wir werden weiter darüber sprechen. 🤷

Eine PR wofür? Ich bin kein C#-Programmierer. Ich bin seit über 30 Jahren kein professioneller Entwickler mehr.

Ich denke, einige von uns waren sich wirklich klar darüber, was wir wollen, und unsere Anwendungsfälle und sahen diese Bedenken minimiert, wie Sie es gerade wieder getan haben.

Diejenigen von Ihnen, die über das Admin-Skripting hinausgehen, denken "mach es einfach zu einem Modul". Die meisten Admin-Skripter werden nicht wissen, wie und sie werden sagen (und ich stimme zu), dass es zu viel Mühe macht, wenn sie die Anforderungen sehen.

Aber das ist sinnlos und ich wusste es besser. Die Schlussfolgerung des PowerShell-Ausschusses ist bereits gefallen. Entschuldigung, dass ich kommentiert habe.

Die Schlussfolgerung des PowerShell-Ausschusses ist bereits gefallen.

Alle Schlussfolgerungen aus dem Entwurf können auf der Grundlage von Rückmeldungen überdacht werden.

Ich denke, einige von uns waren sich wirklich klar darüber, was wir wollen, und unsere Anwendungsfälle und sahen diese Bedenken minimiert, wie Sie es gerade wieder getan haben.

Ich habe wirklich hart versucht, dem eigentlichen Ziel und den Anwendungsfällen auf den Grund zu gehen, und meine Fragen wurden größtenteils ignoriert. Ich würde es wirklich gerne verstehen.

Diejenigen von Ihnen, die über das Admin-Skripting hinausgehen

Mann, ich bin ein Systemadministrator. Den größten Teil meiner Karriere verbrachte ich damit, zu denken, die Hashtable-Syntax sei "die Splatting-Syntax". Die meisten meiner Mitarbeiter kennen nur die absoluten Grundlagen von PowerShell (wenn überhaupt), ebenso wie die meisten Leute, denen ich bei Discord/Reddit helfe.

Ich verstehe, dass Sie mit dem PS-Entwicklerteam etwas zu tun haben, aber bitte tun Sie nicht so, als ob ich Ihre Perspektive nicht verstehen könnte, weil ich C# jetzt zufällig kenne. Ich kämpfe ständig für diese Perspektive in diesem Repo.

Denke "mach es einfach zu einem Modul". Die meisten Admin-Skripter werden nicht wissen, wie und sie werden sagen (und ich stimme zu), dass es zu viel Mühe macht, wenn sie die Anforderungen sehen.

Für alle, die später auf diesen Thread stoßen und davon abgehalten werden, ein Modul zu erstellen, hier die Anforderungen:

  1. Benennen Sie Ihre .ps1 Datei in .psm1
  2. Verwenden Sie Import-Module ./file.psm1 anstelle von . ./file.ps1

Das war's, Sie haben ein Modul. Alles andere sind nur Best Practices, über die Sie sich noch keine Gedanken machen müssen. Wenn Sie es versionieren möchten, benötigen Sie ein Manifest. Hier sind die vollständigen Anforderungen dafür:

  1. Benennen Sie Ihre .ps1 Datei in .psm1
  2. New-ModuleManifest -RootModule ./file.psm1 -Path ./file.psd1 -ModuleVersion 1.0.0
  3. Verwenden Sie Import-Module ./file.psd1 anstelle von . ./file.ps1

Wenn Sie eine lose Funktion in einer ps1 ausliefern, die der Verbraucher (oder Sie selbst) als Dot Source benötigen würde, werfen Sie sie einfach ganz schnell in ein Modul, es wird Ihr Leben einfacher machen.

Wenn Sie ein direkt aufrufbares Skript versenden, können Sie New-ScriptFileInfo wodurch eine Skriptdatei mit einem Kommentar wie diesem generiert wird:

<#PSScriptInfo

.VERSION 1.0.0

.GUID xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

.AUTHOR username

.COMPANYNAME

.COPYRIGHT

.TAGS

.LICENSEURI

.PROJECTURI

.ICONURI

.EXTERNALMODULEDEPENDENCIES 

.REQUIREDSCRIPTS

.EXTERNALSCRIPTDEPENDENCIES

.RELEASENOTES


.PRIVATEDATA

#>

<# 
.DESCRIPTION 
     Quick script description here.
#> 
param()

Und das können Sie mit Test-ScriptFileInfo abfragen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen