Wszystko, co chciałeś wiedzieć o aplikacji ShouldProcess
Funkcje programu PowerShell mają kilka funkcji, które znacznie usprawniają sposób interakcji użytkowników z nimi.
Jedną z ważnych funkcji, która jest często pomijana, jest -WhatIf
obsługa i -Confirm
łatwo jest dodać ją do funkcji. W tym artykule szczegółowo dowiesz się, jak zaimplementować tę funkcję.
Uwaga
Oryginalna wersja tego artykułu pojawiła się na blogu napisanym przez @KevinMarquette. Zespół programu PowerShell dziękuje Kevinowi za udostępnienie tej zawartości nam. Zapoznaj się ze swoim blogiem na PowerShellExplained.com.
Jest to prosta funkcja, którą można włączyć w funkcjach w celu zapewnienia sieci bezpieczeństwa dla użytkowników, którzy jej potrzebują. Nie ma nic przerażającego niż uruchomienie polecenia, które wiesz, że może być niebezpieczne po raz pierwszy. Opcja jej uruchamiania -WhatIf
może mieć dużą różnicę.
Typowe parametry
Zanim przyjrzymy się implementacji tych typowych parametrów, chcę szybko przyjrzeć się sposobom ich użycia.
Korzystanie z parametru -WhatIf
Gdy polecenie obsługuje -WhatIf
parametr , pozwala zobaczyć, co zrobiłoby to polecenie zamiast wprowadzać zmiany. Jest to dobry sposób na przetestowanie wpływu polecenia, zwłaszcza przed wykonaniem czegoś destrukcyjnego.
PS C:\temp> Get-ChildItem
Directory: C:\temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 4/19/2021 8:59 AM 0 importantfile.txt
-a---- 4/19/2021 8:58 AM 0 myfile1.txt
-a---- 4/19/2021 8:59 AM 0 myfile2.txt
PS C:\temp> Remove-Item -Path .\myfile1.txt -WhatIf
What if: Performing the operation "Remove File" on target "C:\Temp\myfile1.txt".
Jeśli polecenie poprawnie implementuje ShouldProcess
polecenie , powinno zostać wyświetlone wszystkie wprowadzone zmiany. Oto przykład użycia symbolu wieloznakowego do usunięcia wielu plików.
PS C:\temp> Remove-Item -Path * -WhatIf
What if: Performing the operation "Remove File" on target "C:\Temp\myfile1.txt".
What if: Performing the operation "Remove File" on target "C:\Temp\myfile2.txt".
What if: Performing the operation "Remove File" on target "C:\Temp\importantfile.txt".
Korzystanie z opcji -Confirm
Polecenia, które obsługują -WhatIf
również obsługę -Confirm
polecenia . Daje to prawdopodobieństwo potwierdzenia akcji przed wykonaniem.
PS C:\temp> Remove-Item .\myfile1.txt -Confirm
Confirm
Are you sure you want to perform this action?
Performing the operation "Remove File" on target "C:\Temp\myfile1.txt".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
W takim przypadku masz wiele opcji, które umożliwiają kontynuowanie, pomijanie zmiany lub zatrzymywanie skryptu. W wierszu pomocy opisano każdą z tych opcji w następujący sposób.
Y - Continue with only the next step of the operation.
A - Continue with all the steps of the operation.
N - Skip this operation and proceed with the next operation.
L - Skip this operation and all subsequent operations.
S - Pause the current pipeline and return to the command prompt. Type "exit" to resume the pipeline.
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
Lokalizacja
Ten monit jest zlokalizowany w programie PowerShell, więc język zmienia się na podstawie języka systemu operacyjnego. Jest to jeszcze jedna rzecz, którą zarządza program PowerShell.
Parametry przełącznika
Poświęćmy chwilę, aby przyjrzeć się sposobom przekazywania wartości do parametru switch. Głównym powodem, dla którego to nazywam, jest to, że często chcesz przekazać wartości parametrów do funkcji, które wywołujesz.
Pierwsze podejście to określona składnia parametrów, która może być używana dla wszystkich parametrów, ale najczęściej jest używana do parametrów przełącznika. Należy określić dwukropek, aby dołączyć wartość do parametru.
Remove-Item -Path:* -WhatIf:$true
Możesz to zrobić za pomocą zmiennej.
$DoWhatIf = $true
Remove-Item -Path * -WhatIf:$DoWhatIf
Drugim podejściem jest użycie tabeli skrótu w celu splatowania wartości.
$RemoveSplat = @{
Path = '*'
WhatIf = $true
}
Remove-Item @RemoveSplat
Jeśli dopiero zaczynasz korzystać z tabel skrótów lub przeplatania, mam inny artykuł, który obejmuje wszystko, co chciałeś wiedzieć o tabelach skrótów.
SupportsShouldProcess
Pierwszym krokiem do włączenia -WhatIf
i -Confirm
obsługi jest określenie SupportsShouldProcess
w CmdletBinding
funkcji .
function Test-ShouldProcess {
[CmdletBinding(SupportsShouldProcess)]
param()
Remove-Item .\myfile1.txt
}
Określając SupportsShouldProcess
w ten sposób, możemy teraz wywołać naszą funkcję za pomocą -WhatIf
funkcji (lub -Confirm
).
PS> Test-ShouldProcess -WhatIf
What if: Performing the operation "Remove File" on target "C:\Temp\myfile1.txt".
Zwróć uwagę, że nie utworzono parametru o nazwie -WhatIf
. Określenie SupportsShouldProcess
automatycznie powoduje utworzenie go dla nas. Po określeniu parametru w elemecie -WhatIf
Test-ShouldProcess
niektóre wywoływane elementy również wykonują -WhatIf
przetwarzanie.
Ufaj, ale weryfikuj
Istnieje pewne niebezpieczeństwo, że wszystko, co wywołujesz, dziedziczy -WhatIf
wartości. W pozostałych przykładach zakładam, że nie działa i jest bardzo wyraźny podczas wykonywania wywołań do innych poleceń. Polecam, że robisz to samo.
function Test-ShouldProcess {
[CmdletBinding(SupportsShouldProcess)]
param()
Remove-Item .\myfile1.txt -WhatIf:$WhatIfPreference
}
Będę ponownie niuanse znacznie później, gdy masz lepsze zrozumienie wszystkich utworów w grze.
$PSCmdlet.ShouldProcess
Metoda, która umożliwia zaimplementowanie SupportsShouldProcess
, to $PSCmdlet.ShouldProcess
. Wywołaj metodę $PSCmdlet.ShouldProcess(...)
, aby sprawdzić, czy należy przetworzyć logikę, a program PowerShell zajmie się resztą. Zacznijmy od przykładu:
function Test-ShouldProcess {
[CmdletBinding(SupportsShouldProcess)]
param()
$file = Get-ChildItem './myfile1.txt'
if($PSCmdlet.ShouldProcess($file.Name)){
$file.Delete()
}
}
Wywołanie funkcji $PSCmdlet.ShouldProcess($file.name)
sprawdzania parametru -WhatIf
(i -Confirm
) następnie obsługuje je odpowiednio. ShouldProcess
Przyczyny -WhatIf
wyprowadzania opisu zmiany i zwracania $false
:
PS> Test-ShouldProcess -WhatIf
What if: Performing the operation "Test-ShouldProcess" on target "myfile1.txt".
Wywołanie przy użyciu wstrzymuje -Confirm
skrypt i wyświetla użytkownikowi monit o kontynuowanie. Zwraca wartość $true
, jeśli użytkownik wybrał pozycję Y
.
PS> Test-ShouldProcess -Confirm
Confirm
Are you sure you want to perform this action?
Performing the operation "Test-ShouldProcess" on target "myfile1.txt".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"):
Niesamowitą $PSCmdlet.ShouldProcess
cechą jest to, że podwaja się jako pełne dane wyjściowe. Często polegam na tym podczas implementowania ShouldProcess
.
PS> Test-ShouldProcess -Verbose
VERBOSE: Performing the operation "Test-ShouldProcess" on target "myfile1.txt".
Przeciążenia
Istnieje kilka różnych przeciążeń funkcji $PSCmdlet.ShouldProcess
z różnymi parametrami dostosowywania komunikatów. W powyższym przykładzie widzieliśmy już pierwszy. Przyjrzyjmy się temu bliżej.
function Test-ShouldProcess {
[CmdletBinding(SupportsShouldProcess)]
param()
if($PSCmdlet.ShouldProcess('TARGET')){
# ...
}
}
Spowoduje to wygenerowanie danych wyjściowych, które zawierają zarówno nazwę funkcji, jak i docelową (wartość parametru).
What if: Performing the operation "Test-ShouldProcess" on target "TARGET".
Określenie drugiego parametru jako operacji używa wartości operacji zamiast nazwy funkcji w komunikacie.
## $PSCmdlet.ShouldProcess('TARGET','OPERATION')
What if: Performing the operation "OPERATION" on target "TARGET".
Następną opcją jest określenie trzech parametrów w celu pełnego dostosowania komunikatu. Gdy są używane trzy parametry, pierwszy z nich to cały komunikat. Dwa drugie parametry są nadal używane w danych wyjściowych komunikatu -Confirm
.
## $PSCmdlet.ShouldProcess('MESSAGE','TARGET','OPERATION')
What if: MESSAGE
Dokumentacja szybkiego parametru
Na wypadek, gdyby przyszedł tutaj tylko dowiedzieć się, jakich parametrów należy użyć, oto krótki przewodnik pokazujący, jak parametry zmieniają komunikat w różnych -WhatIf
scenariuszach.
## $PSCmdlet.ShouldProcess('TARGET')
What if: Performing the operation "FUNCTION_NAME" on target "TARGET".
## $PSCmdlet.ShouldProcess('TARGET','OPERATION')
What if: Performing the operation "OPERATION" on target "TARGET".
## $PSCmdlet.ShouldProcess('MESSAGE','TARGET','OPERATION')
What if: MESSAGE
Zwykle używam tego z dwoma parametrami.
ShouldProcessReason
Mamy czwarte przeciążenie, które jest bardziej zaawansowane niż inne. Pozwala to uzyskać przyczynę ShouldProcess
wykonania. Dodawaję to tylko tutaj, aby uzyskać kompletność, ponieważ możemy tylko sprawdzić, czy $WhatIfPreference
zamiast tego jest $true
.
$reason = ''
if($PSCmdlet.ShouldProcess('MESSAGE','TARGET','OPERATION',[ref]$reason)){
Write-Output "Some Action"
}
$reason
Musimy przekazać zmienną $reason
do czwartego parametru jako zmienną referencyjną z parametrem [ref]
. ShouldProcess
wypełnia $reason
wartość None
lub WhatIf
. Nie powiedziałem, że to było przydatne i nie miałem powodu, aby kiedykolwiek go używać.
Gdzie go umieścić
Użyj polecenia ShouldProcess
, aby zwiększyć bezpieczeństwo skryptów. Dlatego używasz go podczas wprowadzania zmian przez skrypty. Lubię umieścić $PSCmdlet.ShouldProcess
połączenie tak blisko zmiany, jak to możliwe.
## general logic and variable work
if ($PSCmdlet.ShouldProcess('TARGET','OPERATION')){
# Change goes here
}
Jeśli przetwarzam kolekcję elementów, wywołaję ją dla każdego elementu. Dlatego wywołanie zostaje umieszczone wewnątrz pętli foreach.
foreach ($node in $collection){
# general logic and variable work
if ($PSCmdlet.ShouldProcess($node,'OPERATION')){
# Change goes here
}
}
Powodem, dla którego umieszczam ShouldProcess
ściśle wokół zmiany, jest to, że chcę wykonać jak najwięcej kodu, jak to możliwe, gdy -WhatIf
jest określony. Chcę, aby instalacja i walidacja były uruchamiane, jeśli to możliwe, aby użytkownik mógł zobaczyć te błędy.
Lubię również używać tego w testach Pester, które weryfikują moje projekty. Jeśli mam kawałek logiki, który jest trudny do wyśmiewać w pester, często mogę owinąć go ShouldProcess
i nazwać go -WhatIf
w moich testach. Lepiej przetestować część kodu niż żaden z nich.
$WhatIfPreference
Pierwszą zmienną preferencji, która mamy, jest $WhatIfPreference
. $false
Jest to domyślnie. Jeśli ustawisz ją na $true
, funkcja jest wykonywana tak, jakby została określona -WhatIf
. Jeśli ustawisz to w sesji, wszystkie polecenia wykonują -WhatIf
wykonywanie.
Po wywołaniu funkcji za pomocą -WhatIf
funkcji wartość $WhatIfPreference
zostanie ustawiona na $true
wewnątrz zakresu funkcji.
ConfirmImpact
Większość moich przykładów dotyczy -WhatIf
, ale do tej pory wszystko działa również z monitem -Confirm
użytkownika. Możesz ustawić ConfirmImpact
funkcję na wysoką i wyświetlić monit o wywołanie elementu za pomocą polecenia -Confirm
.
function Test-ShouldProcess {
[CmdletBinding(
SupportsShouldProcess,
ConfirmImpact = 'High'
)]
param()
if ($PSCmdlet.ShouldProcess('TARGET')){
Write-Output "Some Action"
}
}
To wywołanie Test-ShouldProcess
powoduje wykonanie -Confirm
akcji ze względu na High
wpływ.
PS> Test-ShouldProcess
Confirm
Are you sure you want to perform this action?
Performing the operation "Test-ShouldProcess" on target "TARGET".
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): y
Some Action
Oczywistym problemem jest to, że teraz trudniej jest użyć w innych skryptach bez monitowania użytkownika. W takim przypadku możemy przekazać wartość , $false
aby -Confirm
pominąć monit.
PS> Test-ShouldProcess -Confirm:$false
Some Action
Omówię sposób dodawania -Force
obsługi w późniejszej sekcji.
$ConfirmPreference
$ConfirmPreference
to zmienna automatyczna, która steruje monitem ConfirmImpact
o potwierdzenie wykonania. Poniżej przedstawiono możliwe wartości dla parametrów $ConfirmPreference
i ConfirmImpact
.
High
Medium
Low
None
Za pomocą tych wartości można określić różne poziomy wpływu dla każdej funkcji. Jeśli ustawiono $ConfirmPreference
wartość wyższą niż ConfirmImpact
, nie zostanie wyświetlony monit o potwierdzenie wykonania.
Domyślnie $ConfirmPreference
jest ustawiona wartość High
i ConfirmImpact
ma wartość Medium
. Jeśli chcesz, aby funkcja automatycznie monitować użytkownika, ustaw wartość ConfirmImpact
High
. W przeciwnym razie ustaw go na Medium
wartość , jeśli jego destrukcyjne i użyj Low
, jeśli polecenie jest zawsze bezpieczne w środowisku produkcyjnym. Jeśli ustawisz go na none
wartość , nie wyświetla monitu, nawet jeśli -Confirm
został określony (ale nadal zapewnia -WhatIf
pomoc techniczną).
Podczas wywoływania funkcji za pomocą -Confirm
parametru $ConfirmPreference
wartość zostaje ustawiona na Low
wewnątrz zakresu funkcji.
Pomijanie zagnieżdżonych monitów o potwierdzenie
Element $ConfirmPreference
może być odbierany przez wywoływane funkcje. Może to tworzyć scenariusze, w których dodajesz monit o potwierdzenie, a wywołana funkcja również monituje użytkownika.
Mam tendencję do określania -Confirm:$false
poleceń, które wywołujem, gdy już obsłużyłem monit.
function Test-ShouldProcess {
[CmdletBinding(SupportsShouldProcess)]
param()
$file = Get-ChildItem './myfile1.txt'
if($PSCmdlet.ShouldProcess($file.Name)){
Remove-Item -Path $file.FullName -Confirm:$false
}
}
Powoduje to powrót do wcześniejszego ostrzeżenia: istnieją niuanse, gdy -WhatIf
nie jest przekazywany do funkcji i kiedy -Confirm
przekazuje do funkcji. Obiecuję, że wrócę do tego później.
$PSCmdlet.ShouldContinue
Jeśli potrzebujesz większej kontroli niż ShouldProcess
zapewnia, możesz wyzwolić monit bezpośrednio za pomocą polecenia ShouldContinue
. ShouldContinue
Ignoruje $ConfirmPreference
wartości , , ConfirmImpact
-Confirm
, $WhatIfPreference
i -WhatIf
, ponieważ wyświetla monit za każdym razem, gdy jest wykonywany.
Na szybki rzut oka łatwo się mylą ShouldProcess
i ShouldContinue
. Zwykle pamiętam, aby użyć ShouldProcess
, ponieważ parametr jest wywoływany SupportsShouldProcess
w pliku CmdletBinding
.
Należy używać ShouldProcess
w niemal każdym scenariuszu. Dlatego najpierw omówiłem tę metodę.
Przyjrzyjmy ShouldContinue
się w działaniu.
function Test-ShouldContinue {
[CmdletBinding()]
param()
if($PSCmdlet.ShouldContinue('TARGET','OPERATION')){
Write-Output "Some Action"
}
}
Zapewnia to prostszy monit z mniejszą liczbą opcji.
Test-ShouldContinue
Second
TARGET
[Y] Yes [N] No [S] Suspend [?] Help (default is "Y"):
Największym problemem jest ShouldContinue
to, że wymaga, aby użytkownik uruchamiał go interaktywnie, ponieważ zawsze monituje użytkownika. Zawsze należy tworzyć narzędzia, które mogą być używane przez inne skrypty. W ten sposób należy zaimplementować element -Force
. Wrócę do tego pomysłu później.
Tak dla wszystkich
Jest to obsługiwane automatycznie, ShouldProcess
ale musimy wykonać nieco więcej pracy dla programu ShouldContinue
. Istnieje drugie przeciążenie metody, w której musimy przekazać kilka wartości, odwołując się do kontroli logiki.
function Test-ShouldContinue {
[CmdletBinding()]
param()
$collection = 1..5
$yesToAll = $false
$noToAll = $false
foreach($target in $collection) {
$continue = $PSCmdlet.ShouldContinue(
"TARGET_$target",
'OPERATION',
[ref]$yesToAll,
[ref]$noToAll
)
if ($continue){
Write-Output "Some Action [$target]"
}
}
}
Dodano pętlę foreach
i kolekcję, aby pokazać ją w akcji. Wyciągnąłem ShouldContinue
wezwanie z if
oświadczenia, aby ułatwić czytanie. Wywołanie metody z czterema parametrami zaczyna się trochę brzydkie, ale starałem się, aby wyglądało to tak czyste, jak mogłem.
Implementowanie -Force
ShouldProcess
i ShouldContinue
muszą implementować -Force
na różne sposoby. Sztuczką dla tych implementacji jest to, że ShouldProcess
zawsze powinny być wykonywane, ale ShouldContinue
nie powinny być wykonywane, jeśli -Force
jest określony.
ShouldProcess - Force
Jeśli ustawisz ConfirmImpact
high
wartość na , pierwszą rzeczą, którą użytkownicy spróbują, jest pominięcie go za pomocą polecenia -Force
. To pierwsza rzecz, którą mimo to robię.
Test-ShouldProcess -Force
Error: Test-ShouldProcess: A parameter cannot be found that matches parameter name 'force'.
Jeśli pamiętasz z ConfirmImpact
sekcji, faktycznie muszą wywołać ją w następujący sposób:
Test-ShouldProcess -Confirm:$false
Nie każdy zdaje sobie sprawę, że musi to zrobić i -Force
nie pomija ShouldContinue
.
Dlatego powinniśmy zaimplementować -Force
zasady rozsądku naszych użytkowników. Zapoznaj się z tym pełnym przykładem tutaj:
function Test-ShouldProcess {
[CmdletBinding(
SupportsShouldProcess,
ConfirmImpact = 'High'
)]
param(
[Switch]$Force
)
if ($Force -and -not $Confirm){
$ConfirmPreference = 'None'
}
if ($PSCmdlet.ShouldProcess('TARGET')){
Write-Output "Some Action"
}
}
Dodamy własny -Force
przełącznik jako parametr. Parametr -Confirm
jest automatycznie dodawany podczas używania SupportsShouldProcess
w elem.CmdletBinding
[CmdletBinding(
SupportsShouldProcess,
ConfirmImpact = 'High'
)]
param(
[Switch]$Force
)
Tutaj skupiamy się na logice -Force
:
if ($Force -and -not $Confirm){
$ConfirmPreference = 'None'
}
Jeśli użytkownik określi wartość , chcemy -Force
pominąć monit o potwierdzenie, chyba że określi również wartość -Confirm
. Dzięki temu użytkownik może wymusić zmianę, ale nadal potwierdzić zmianę. Następnie ustawiliśmy $ConfirmPreference
zakres lokalny. Teraz, używając parametru -Force
tymczasowo ustawia $ConfirmPreference
wartość na brak, wyłączając monit o potwierdzenie.
if ($PSCmdlet.ShouldProcess('TARGET')){
Write-Output "Some Action"
}
Jeśli ktoś określi wartości i -Force
-WhatIf
, -WhatIf
musi mieć priorytet. Takie podejście zachowuje -WhatIf
przetwarzanie, ponieważ ShouldProcess
zawsze jest wykonywane.
Nie należy dodawać sprawdzania $Force
wartości wewnątrz instrukcji if
za pomocą .ShouldProcess
Jest to antywzór dla tego konkretnego scenariusza, mimo że to, co pokazujem w następnej sekcji dla .ShouldContinue
ShouldContinue - Force
Jest to prawidłowy sposób implementacji -Force
za pomocą ShouldContinue
polecenia .
function Test-ShouldContinue {
[CmdletBinding()]
param(
[Switch]$Force
)
if($Force -or $PSCmdlet.ShouldContinue('TARGET','OPERATION')){
Write-Output "Some Action"
}
}
Umieszczając element z $Force
lewej -or
strony operatora, zostaje on oceniony jako pierwszy. Napisanie go w ten sposób powoduje zwarcie wykonania instrukcji if
. Jeśli $force
parametr ma $true
wartość , ShouldContinue
parametr nie jest wykonywany.
PS> Test-ShouldContinue -Force
Some Action
Nie musimy się martwić -Confirm
ani -WhatIf
w tym scenariuszu, ponieważ nie są one obsługiwane przez ShouldContinue
usługę . Dlatego musi być obsługiwana inaczej niż ShouldProcess
.
Problemy z zakresem
Używanie elementów -WhatIf
i -Confirm
mają mieć zastosowanie do wszystkiego wewnątrz funkcji i wszystkiego, co wywołuje. W tym celu należy ustawić $true
$WhatIfPreference
wartość lub ustawić Low
wartość $ConfirmPreference
w lokalnym zakresie funkcji. Wywołanie innej funkcji w celu ShouldProcess
użycia tych wartości.
To działa poprawnie przez większość czasu. Za każdym razem, gdy wywołujesz wbudowane polecenie cmdlet lub funkcję w tym samym zakresie, działa. Działa również podczas wywoływania skryptu lub funkcji w module skryptu z konsoli programu .
Jednym konkretnym miejscem, w którym nie działa, jest to, gdy skrypt lub moduł skryptu wywołuje funkcję w innym module skryptu. Może to nie wydawać się dużym problemem, ale większość modułów utworzonych lub ściągniętych z programu PSGallery to moduły skryptów.
Podstawowym problemem jest to, że moduły skryptów nie dziedziczą wartości dla $WhatIfPreference
lub $ConfirmPreference
(i kilku innych), gdy są wywoływane z funkcji w innych modułach skryptu.
Najlepszym sposobem, aby podsumować to jako ogólną regułę jest to, że działa to poprawnie w przypadku modułów binarnych i nigdy nie ufaj, że działa w przypadku modułów skryptów. Jeśli nie masz pewności, przetestuj go lub po prostu załóżmy, że nie działa poprawnie.
Osobiście czuję, że jest to bardzo niebezpieczne, ponieważ tworzy scenariusze, w których dodajesz -WhatIf
obsługę wielu modułów, które działają poprawnie w izolacji, ale nie działają poprawnie, gdy się dzwonią.
Pracujemy nad rozwiązaniem tego problemu w usłudze GitHub RFC. Aby uzyskać więcej szczegółów, zobacz Propagacja preferencji wykonywania poza zakresem modułu skryptu.
Zamykanie
Muszę wyszukać, jak używać ShouldProcess
za każdym razem, gdy muszę go używać. To zajęło mi dużo czasu, aby odróżnić ShouldProcess
się od ShouldContinue
. Prawie zawsze muszę wyszukać, jakich parametrów użyć. Więc nie martw się, jeśli nadal masz zdezorientowany od czasu do czasu. Ten artykuł będzie tutaj, gdy będzie potrzebny. Jestem pewien, że będę się do niego często odwoływać.
Jeśli podoba Ci się ten post, podziel się swoimi przemyśleniami ze mną na Twitterze, korzystając z poniższego linku. Zawsze lubię słyszeć od ludzi, którzy otrzymują wartość z mojej treści.
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla