Skrypt PowerShell, który omawiam w tym wpisie, umożliwia utrzymywanie zapisanych poświadczeń dla konkretnych zasobów sieciowych w Windows Credential Manager. Impulsem do jego przygotowania była polityka GPO, która cyklicznie usuwała zapisane dane logowania, w efekcie uniemożliwiając poprawne wykonanie backupu plików na udziale sieciowym. W takiej sytuacji naturalnym pytaniem jest, czy nie prostszym rozwiązaniem byłaby modyfikacja polityki GPO. W tym konkretnym przypadku nie było to jednak możliwe, dlatego znacznie szybszym, wygodniejszym i mniej inwazyjnym rozwiązaniem okazało się stworzenie mechanizmu, który automatycznie odtwarza wymagane poświadczenia.
Ważne
Kolejne materiały 04.01.2026. Muszę chwilę odpocząć. Możliwe, że dziś mailing nie wyjdzie, mam problem u dostawcy. Wyślę, jak tylko problem zostanie rozwiązany.
Hash hasła
Pierwszym krokiem jest przygotowanie hasła w pliku z rozszerzeniem .cred. Hasło, czy raczej hash hasła powinien być oczywiście dostępny jedynie dla konta, które będzie sprawdzać czy wpis w Windows Credentials będzie dostępny. Jeżeli z uruchomieniem skryptu będzie problem, warto wygenerować plik z hashem hasła jako użykownik, który ma docelowo uruchamiać skrypt.
|
1 |
Read-Host "Podaj hasło" -AsSecureString | Export-Clixml C:\backup.cred |
Powyższy wiersz uruchamiamy oczywiście raz, jedynie aby podać hasło oraz wygenerować plik backup.cread.

Skrypt pilnujący Windows Credentials
Właściwy skrypt, który będzie dodany do schedulera poniżej. W zależności od potrzeb może być uruchamiany w momencie uruchomienia maszyny lub co określony czas, np. 15 minut.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$Target = "192.168.8.100" # zmień na swój adres $User = "$Target\backup" #zmień na swój login $CredFile = "C:\backup.cred" #wskaż plik z hashem hasła if (-not (Test-Path $CredFile)) { Write-Error "Brak pliku z hasłem: $CredFile" exit 1 } $exists = cmdkey /list | Select-String $Target if (-not $exists) { $SecurePassword = Import-Clixml $CredFile $PlainPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto( [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword) ) cmdkey /add:$Target /user:$User /pass:$PlainPassword $PlainPassword = $null } |
Definicja zmiennych konfiguracyjnych
|
1 2 3 4 |
$Target = "192.168.8.100" # zmień na swój adres $User = "$Target\backup" #zmień na swój login $CredFile = "C:\backup.cred" #wskaż plik z hash hasła |
$Target– adres IP / host, dla którego zapisane będą poświadczenia$User– login w formacieHOST\USER
(konto lokalne na zdalnym systemie)$CredFile – plik zawierający zaszyfrowane hasło (SecureString)
Utworzony wcześniej przezExport-Clixml- działa tylko na tym koncie i komputerze
Sprawdzenie istnienia pliku z hasłem
|
1 2 3 4 5 |
if (-not (Test-Path $CredFile)) { Write-Error "Brak pliku z hasłem: $CredFile" exit 1 } |
- zabezpieczenie przed:
- błędem odszyfrowania
- pustym hasłem
- dodaniem niepoprawnego credentiala
Jeśli plik nie istnieje:
- skrypt kończy działanie
- zgłasza błąd
Sprawdzenie, czy poświadczenie już istnieje
|
1 2 |
$exists = cmdkey /list | Select-String $Target |
cmdkey /list– wypisuje wszystkie zapisane poświadczeniaSelect-String $Target – filtruje wynik po adresie IP
- jeśli credential istnieje →
$exists≠$null - jeśli nie →
$exists=$null
Warunek „dodaj tylko jeśli brak”
|
1 2 |
if (-not $exists) { |
- zapobiega:
- nadpisywaniu istniejących danych
- niepotrzebnemu zapisywaniu hasła
- spamowaniu Credential Managera
Wczytanie zaszyfrowanego hasła
|
1 2 |
$SecurePassword = Import-Clixml $CredFile |
- odczytuje obiekt
SecureString - odszyfrowanie odbywa się automatycznie przez DPAPI
- możliwe tylko na:
- tym komputerze
- tym koncie użytkownika
Konwersja SecureString → zwykły tekst (tymczasowo)
|
1 2 3 4 |
$PlainPassword = [Runtime.InteropServices.Marshal]::PtrToStringAuto( [Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword) ) |
- wymagane, bo
cmdkeynie obsługuje SecureString - hasło:
- istnieje w pamięci tylko chwilowo
- nie jest zapisywane do pliku ani logów
To standardowa technika Microsoftu
Dodanie poświadczeń do Windows Credential Manager
|
1 2 |
cmdkey /add:$Target /user:$User /pass:$PlainPassword |
Efekt:
- w Credential Managerze pojawia się:
- Target:
192.168.8.100 - User:
192.168.8.100\backup - Password: zapisane bezpiecznie przez Windows
- Target:
Poświadczenia są używane m.in. przez:
- SMB
- mapowanie dysków
- backup
- usługi
Czyszczenie hasła z pamięci
|
1 2 |
$PlainPassword = $null |
- usuwa hasło z RAM
- dobra praktyka bezpieczeństwa
- minimalizuje ryzyko wycieku
Harmonogram zadań
Przykładowa konfiguracja w harmonogramie poniżej.



Program/script: powershell.exe
Add arguments (optional): -ExecutionPolicy Bypass -NoProfile -File „C:\Windows_Credentials.ps1”



Podsumowanie
Skrypt PowerShell został zaprojektowany w celu automatycznego i bezpiecznego zarządzania poświadczeniami w Windows Credential Manager dla określonego hosta. Jego działanie opiera się na cyklicznym sprawdzaniu, czy wymagane dane logowania są już obecne w systemie, a w przypadku ich braku – na ich ponownym dodaniu z wykorzystaniem lokalnie zapisanego, zaszyfrowanego hasła. Zastosowanie mechanizmu DPAPI sprawia, że hasło nigdy nie jest przechowywane w postaci jawnej i może zostać odszyfrowane wyłącznie na tym samym komputerze oraz w kontekście tego samego konta użytkownika. Dzięki idempotentnej konstrukcji skrypt może być uruchamiany wielokrotnie bez ryzyka niepożądanych efektów, co czyni go idealnym rozwiązaniem do pracy cyklicznej, na przykład z użyciem Harmonogramu zadań. W praktyce zapewnia to nieprzerwaną dostępność usług, procesów backupowych oraz połączeń sieciowych, nawet po restarcie systemu lub ręcznym usunięciu poświadczeń, przy zachowaniu wysokiego poziomu bezpieczeństwa.
Dziękuję Ci, za poświęcony czas na przeczytanie tego artykułu. Jeśli był on dla Ciebie przydatny, to gorąco zachęcam Cię do zapisania się na mój newsletter, jeżeli jeszcze Cię tam nie ma. Proszę Cię także o “polubienie” mojego bloga na Facebooku oraz kanału na YouTube – pomoże mi to dotrzeć do nowych odbiorców. Raz w tygodniu (niedziela punkt 17.00) otrzymasz powiadomienia o nowych artykułach / projektach zanim staną się publiczne. Możesz również pozostawić całkowicie anonimowy pomysł na wpis/nagranie.
Link do formularza tutaj: https://beitadmin.pl/pomysly
Pozostaw również komentarz lub napisz do mnie wiadomość odpisuję na każdą, jeżeli Masz jakieś pytania:).