2021-04-17
Taki oto błąd może się pojawić podczas intalacji PostgreSQL na Windows:
The environment variable COMSPEC does not seem to point to the cmd.exe or there is a trailing semicolon present
COMSPEC to zmienna środowiskowa wskazująca na interpreter poleceń w systemie windows. Interpreter poleceń, to po prostu program cmd.exe. Może się zdarzyć, że wskutek jakieś innej nieudanej operacji, względnie infekcji wirusem, ta zminna może być niepoprawnie ustawiona. W takim przypadku trzeba zmodyfikować tą zmienną.
Kliknij na start >> odszukaj „Mój komputer” >> kliknij ikonkę prawym przyciskiem myszy i wybierz właściwości >> w oknie wybieraj kolejne pozycje dochodząc w końcu do poszukiwanego COMSPEC:

Po modyfikacji zrestartuj komputer
2021-03-28
Podczas dodawania do quorum świadka „Cloud Witness” dostałem błąd:
An error was encountered while modifying the quorum settings.
Your cluster quorum settings have not been changed.
The client and server cannot communicate, because they do not possess a common algorithm.
Dodajmy, że Always On był konfigurowany na Windows 2016.
Przyczyną jest to, że Azure Storage Account pozwala na połąćzenie za pomocą TLS 1.0 1.1 i 1.2, tymczasem na moich serwerach miałem wyższą wersję. Nie wiem, jak obniżyć wykorzystywaną wersję w interfejsie graficznym, ale z powershella robi się to tak:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Set-ClusterQuorum -Cluster Cluster_Name -CloudWitness -AccountName Storage_Account_Name -AccessKey "Storage Access Key 1 or 2"
Pierwsze polecenie obniża wersję TLS, a drugie dodaje cloud witness.
Przy okazji pojawił się też problem podczas samego konfigurowania availability group:
The local node is not part of quorum and is therefore unable to process this operation. This may be due to one of the following reasons:
• The local node is not able to communicate with the WSFC cluster.
• No quorum set across the WSFC cluster.
For more information on recovering from quorum loss, refer to SQL Server Books Online.
(Microsoft.SqlServer.Management.HadrTasks)
Zazwyczaj ten błąd oznacza rzeczywiście problem z clustrem, względnie przyczyną jest to, że we właściwościach usługi SQL w Configuration Managerze nie jest zaznaczona opcja Enable AlwaysOn Availability Groups:

Istotne jest jednak żeby ta opcja została zaznaczona PO utworzeniu clustra. Jeśli w między czasie cluster został odinstalowany i zainstalowany na nowo, to trzeba tę opcję wyłączyć (restart SQL) i włączyć (restart SQL)
https://docs.microsoft.com/en-us/azure/azure-sql/virtual-machines/windows/availability-group-clusterless-workgroup-configure
2021-03-22
Większość terminali, zarówno na Unix, jak i pod Windows obsługują „kody ucieczki” pozwalające na takie sformatowanie napisu wyświetlanego w konsoli poleceniem print, aby wyświetlany tekst otrzymał odpowiedni kolor.
Szczegółowo ten mechanizm jest opisany tutaj:
https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
Jeśli jednak chcesz ominąć czytanie długiej dokumentacji, bo po prostu chcesz wyświetlić coś na kolorowo, to powinno wystarczyć rozumienie poniższej instrukcji:
print('\x1b[38;2;255;0;0m\x1b[48;2;255;255;0m' + 'WWW.MOBILO24.EU!' + '\x1b[0m')

Co tu się dzieje?
- \x1b[ to właśnie znak ucieczki wprowadzający informacje kontrolne dla terminala. Jest to więc coś, co nie jest wyświetlane, tylko interpretuje to sobie terminal. Instrukcja tu zapisana kończy się za literką m. W powyższym przykładzie ta instrukcja występuje aż trzy razy:
- pierwsza wprowadza kolor tekstu (foreground)
- druga wprowadza kolor tła (background)
- a trzecia resetuje terminal do ustawień domyślnych, czyli kasuje informacje o używanych kolorach
- Fragment 38;2;255;0;0 oznacza:
- 38 – określa, że definiujesz kolor tekstu (foreground)
- 2 – określa, że ciąg dalszy jest w formacie RGB
- kolejne 3 liczby definiują kolor RGB – tutaj czerwony
- Fragment 48;2;255;255;0 oznacza:
- 48 – określa, że definiujesz kolor tła (background)
- 2 – określa, że ciąg dalszy jest w formacie RGB
- kolejne 3 liczby definiują kolor RGB – tutaj żółty
- Ostatnia instrukcja to wreszcie reset ustawień terminala, tutaj pomijając znak ucieczki i znak końca instrukcji „m”, istrukcja ta ogranicza się do „0”
- Pośrodku wstawiasz tekst do wyświetlenia
Gotowe!
2021-03-12
W pewnych przypadkach trzeba ustalić jaki adres IPv4 jest przypisany do serwera. Można oczywiście zajrzeć do widoku sys.dm_exec_connections
Niestety ta metoda nie zadziała jeśli połączenie jest nawiązane przez Shared Memory, albo 127.0.0.1 albo (i to mój przypadek) przez IPv6, a tymczasem potrzebowałem IPv4.
Na całe szczęście udało się znaleźć ciekawy pomysł z wykorzystaniem xm_cmdshell i prostego polecenia ipconfig
https://stackoverflow.com/questions/142142/sql-query-to-get-servers-ip-address
Oto delikatnie zmieniona procedura – u mnie działa!
CREATE PROCEDURE #sp_get_ip_address (@ip VARCHAR(40) OUT)
AS
BEGIN
SET NOCOUNT ON
DECLARE @Line varchar(200)
DECLARE @pos int
SET @ip = NULL
CREATE TABLE #temp (line VARCHAR(200))
EXECUTE sp_configure 'show advanced options', 1;
RECONFIGURE
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE
INSERT INTO #temp EXEC master..xp_cmdshell 'ipconfig'
EXECUTE sp_configure 'show advanced options', 1;
RECONFIGURE
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE
SELECT @Line = line
FROM #temp
WHERE UPPER (line) like '%IPV4%ADDRESS%'
IF (ISNULL (@line,'***') != '***')
BEGIN
SET @pos = CHARINDEX (':',@line,1);
SET @ip = RTRIM(LTRIM(SUBSTRING (@line, @pos + 1, LEN(@line) - @pos)))
END
DROP TABLE #temp
SET NOCOUNT OFF
END
GO
DECLARE @ip VARCHAR(40)
EXEC #sp_get_ip_address @ip OUT
DROP PROCEDURE #sp_get_ip_address
SELECT @ip
2021-02-12
No cóż… zdarza się najlepszym…
Jako tako nie wiem, co się zespuło, ale dałem radę naprawić:
- Panel Sterowania
- Dodaj usuń programy
- Odszukaj pakiet Office (może się różnie nazywać, bo MS dostarcza go w różnych pakietach)
- Klinij modyfikuj
- Wybierz napraw. U mnie były dwie możliwości naprawy – szybka i zaawansowana. Wybrałem szybką i po kawie office działał 🙂
Masz lepszy pomysł? Napisz!
2021-02-10
Coraz częściej pracujemy w środowiskach międzynarodowych. Standardem jest używanie języka angielskiego, ale… jeśli na biurku masz klawiaturę francuską, czy niemiecką, to nic dziwnego, że administratorzy konfigurują do wykorzystania również inne „egzotyczne” układy.
W takim przypadku z pewnością chcemy dodać język angielski. Trzeba to zrobić w kilku miejscach:
- Panel sterowania >> język (language) – dodaj język i wybierz kolejność stosowania języków
- Z boku kliknij na „Advanced” i wypełnij odpowiednio pola

- Kliknij „Apply language settings to the welcome screen”, a potem w oknie Region na zakładce Administrative:

- Wybierz Change system locale i zmień język, tak jak chcesz
- Kliknij też Copy settings

- zaznacz „Welcome screen” i „New user accounts”
- Pozamykaj okna i zrestartuj system
Niestety po wszystkim, nadal może sie okazać, że domyślny język wprowadzania danych na ekranie logowania to np. Francuski. W takim przypadku:
- Uruchom gpedit.msc, przejdź do:
Local Policy >> Computer Configuration >> Administrative Templates >> System >> Locale Services
i zmień wartość w „Disallow copying of user input methods to the system account for Sign-in” na Enabled
W moim przypadku, dopiero to ostatnie ustawienie po restarcie spowodowało wyświetlenie języka angielskiego i angielskiej klawiatury na ekranie logowania
2021-02-08
Python jest fajny, bo jest dynamiczny. Napiszesz sobie funkcję, a potem ni z tego ni z owego można ją wywoływać na wiele sposobów. Popatrz na ten przykład:
def show_args(arg_1, arg_2):
print(arg_1)
print(arg_2)
show_args('one','two')
Proste? No pewnie, że proste! Funkcja ma dwa argumenty i wywołujemy ją z dwoma argumentami i już!
Ale może by tak, mając listę dwóch elementów przekazać ją do tej funkcji? Może funkcja będzie na tyle sprytna, żeby zrozumieć o co chodzi? Niestety będzie błąd:
show_args(['one','two'])
TypeError: show_args() missing 1 required positional argument: 'arg_2'
… ale gdyby tak, przed listą dodać gwiazdkę, to Python „wyłuska z listy jej elementy i przekaże je do funkcji:
show_args(*['one','two'])
one
two
Wow! Dobre!
No a jeśli nie mamy listy argumentów, tylko słownik? I jeśli jeszcze w tym słowniku elementy są „przypadkowo” nazwane tak, jak argumenty testowanej funkcji? Przy pierwszym podejściu – niestety klapa:
show_args({'arg_2':'two', 'arg_1':'one'})
TypeError: show_args() missing 1 required positional argument: 'arg_2'
Ale my już wiemy, jak sobie z tym poradzić:
show_args(*{'arg_2':'two', 'arg_1':'one'})
arg_2
arg_1
Jedna gwiazdka jakoś już pomogła, niestety, pewnie wolelibyśmy nie zobaczyć w wyniku funkcji nazw kluczy, tylko ich wartości! Z pomocą przyjdą dwie gwiazdki, które konwertują słownik na nazwane wartości przekazywane do funkcji:
show_args(**{'arg_2':'two', 'arg_1':'one'})
one
two
I to już działa idealnie. Funkcja domyśliła się, co to jest arg_1 mimo tego, że ta wartość w słowniku była dopiero na drugim miejscu.
Fajnie, ale te „chwyty” można też wykorzystać definiując funkcję:
def clever_function(*args):
for a in args:
print(a)
clever_function(1,2,3)
Kiedy chcesz, aby funkcja mogła przyjąć dowolną liczbę parametrów przekazywanych po prostu przez pozycję, to wystarczy zadeklarować argumenty jako *args. W ciele funkcji można wtedy skorzystać ze zmiennej args, która jest listą. Bardzo to elastyczne!
Jeśli z kolei chcesz, aby funkcja miała przyjmować dowolną liczbę argumentów ze słownika, to argument poprzedź dwoma gwiazdkami. Zazwyczaj ten parametr nazywamy kwargs (key-word argument):
def clever_function(**kwargs):
for k, v in kwargs.items():
print(k,v)
clever_function(a=1,b=2,c=3)
Teraz do funkcji można przekazywać dowolną liczbę nazwanych parametrów, a funkcja w sprytny sposób zobaczy je jako słownik. To użytkownik wywołując funkcję sam decyduje o tym, jak mają się nazywać argumenty widoczne w funkcji.
Obie te metody można zresztą połączyć i zbudować funkcję tak:
def clever_function(*args, **kwargs):
for a in args:
print(a)
for k, v in kwargs.items():
print(k,v)
clever_function('one','two',a=1,b=2,c=3)
print('---')
clever_function(a=1,b=2,c=3)
print('---')
clever_function('one','two')
Jak widać funkcję można teraz wywoływać z argumentami określanymi przez pozycję i nazwę, albo tylko przez nazwę albo tylko przez pozycję.
Oj przyda się na pewno!