2017-04-25
Załóżmy, że w swoim skrypcie potrzebujesz rozpoznać, czy dany dzień jest dniem wolnym (sobota lub niedziela) czy roboczym… Proste!
$d = [datetime]::Now
$d.dayofweek
No i świetnie. Wynikiem może na przykład być:
Tuesday
Hmmm, ale czy aby zawsze? Na komputerze z polskimi ustawieniami regionalnymi może zostać zwrócone:
Wtorek
Jeśli chcesz sprawdzić czy dzień jest niedzielą czy sobotą czy innym dniem tygodnia lepszym wyborem byłoby korzystanie z jakiejś wartości liczbowej, gdzie np Niedziela to 0, Poniedziałek to wtorek itp. Da sie coś takiego zrobić. Zrzutuj właściwość DayOfWeek do [int]:
$d = [datetime]::Now
[int]$d.dayofweek
W moim przypadku (wtorek) zwracana wartość to 2. Czy jednak nie będzie tak, że zależnie od ustawień kultury, 0 będzie oznaczać Niedzielę, a w innych warunkach Poniedziałek? Otóż nie!. Jak czytamy na
https://msdn.microsoft.com/pl-pl/library/system.datetime.dayofweek(v=vs.110).aspx
The value of the constants in the DayOfWeek enumeration ranges from DayOfWeek.Sunday to DayOfWeek.Saturday. If cast to an integer, its value ranges from zero (which indicates DayOfWeek.Sunday) to six (which indicates DayOfWeek.Saturday).
The DayOfWeek property returns an enumerated constant; it does not reflect a system’s regional and language settings. To retrieve a string representing a localized weekday name for a particular date, call one of the overloads of the ToString method that includes a format parameter and pass it either the ddd or dddd custom format strings. For details, see How to: Extract the Day of the Week from a Specific Date.
A więc niezależnie od ustawień językowych, regionalnych itp. 0 to zawsze Niedziela a 6 to zawsze Sobota. Wartość stałych można sprawdzić wpisując:
[int][dayofweek]::Sunday
[int][dayofweek]::Monday
[int][dayofweek]::Tuesday
[int][dayofweek]::Wednesday
[int][dayofweek]::Thursday
[int][dayofweek]::Friday
[int][dayofweek]::Saturday
Wynik to oczywiście
0
1
2
3
4
5
6
Jeśli wiec trzeba sprawdzić czy data jest weekendowa wykonaj:
$d = [datetime]::Now
if (($d.DayOfWeek -eq [dayofweek]::Sunday) -or ($d.DayOfWeek -eq [dayofweek]::Saturday))
{
Write-Output "this is weekend"
}
else
{
Write-output "this is NOT a weekend"
}
2017-03-14
Protokół NTLM służy do uwierzytelnienia (authentication), czyli jego celem jest sprawdzenie kto chce wykonać daną czynność (np. zalogować się do komputera lub zdalnie uruchomić proces na komputerze). Jeśli dwa komputery (klient i serwer) znajdowałyby się w domenie AD, a połączenie wykonywano by z wykorzystaniem nazwy komputera to zostałby wykorzystany protokół Kerberos. Jeśli jednak komputery znajdują się w grupie roboczej lub do połączenia wykorzystano adres IP to Windows użyje protokołu NTLM.
Jak wiadomo najbardziej wrażliwą informacją o użytkowniku jest jego hasło i dlatego nikt nie chce przesyłać hasła po sieci. NTLM stosuje więc pewną sztuczkę. Komputer kliencki generuje pewną frazę i szyfruje ją z wykorzystaniem hasła użytkownika. Jest to wyzwanie dla komputera serwera, który musi teraz sprawdzić czy hasło jest poprawne. Skąd się wzięło hasło na komputerze kliencie? To proste – podał je użytkownik! A skąd komputer serwer weźmie poprawne hasło? Zazwyczaj komputer serwer nie zna tego hasła, ale może poprosić o pomoc kontroler domeny. Kontroler jest w stanie dla komputera serwera dokonać przeliczeń na haśle i w ten sposób kontroler domeny pomaga w wygenerowaniu klucza sesyjnego, jakim dalej mogą się posługiwać komputery klient i serwer.
NTLM często bywa wyłączony, bo Kerberos jest bezpieczniejszy! W przypadku Kerberos weryfikowany jest nie tylko klient przed serwerem ale jeszcze dodatkowo serwer przed klientem. W NTML wcale nie ma pewności, że serwer z którym klient się chce połączyć jest rzeczywiście tym do którego się chciało połączyć. NTLM nie chroni administratora przed atakiem man-in-the-mddle.
2017-03-13
Zdarza się, że programista aplikacji z jakiej ma również skorzystać skrypt powershell przewidział wyłacznie interfejs wymiany danych w postaci web service. Zobacz, jak łatwo można korzystać z web service z poziomu Powershell.
Tutaj skorzystamy z publicznie dostępnych web service http://www.webservicex.net
Po pierwsze należy utworzyć obiekt WebServiceProxy, który zostanie zainicjowany adresem web service. W tym przypadku sięgamy po webservice podający dane na temat lotnisk:
$a = New-WebServiceProxy 'http://www.webservicex.net/airport.asmx?WSDL’
Teraz w dokumentacji web service należałoby zobaczyć, jakie metody można wywoływać dla utworzonego web service proxy. Tutaj skorzystaliśmy z GetAirportInformationByCountry:
$a.GetAirportInformationByCountry(’Poland’)
Informacja zwrócona przez web service to oczywiście XML, jednak powershell domyślnie zaprezentuje go w postaci zwykłego tekstu. Aby jednak zobaczyć XML należy zrzutować ten tekst na [xml]. Tak utworzony XML ma element główny o nazwie NewDataSet a w nim element o nazwie Table. Korzystając więc z metody web service getAirportInformationByAirportCode można w czytelny sposób wyświetlić informacje o lotnisku w Poznaniu lub Katowicach:
(([xml]$a.getAirportInformationByAirportCode(’POZ’)).NewDataSet).Table
(([xml]$a.getAirportInformationByAirportCode(’KTW’)).NewDataSet).Table
2017-03-05
Członkowie ODS PTI (Oddział Dolnośląski Polskiego Towarzystwa Informatycznego) mogą uzyskać darmowy dostęp do szkoleń!
Informacja ze strony aktualności ODS PTI
2017-02-21
Niby zdefiniowanie serwera zlinkowanego do Oracle nie powinno być trudne. Jest sporo tutoriali, które pokazują jak to zrobić. Kiedy jednak coś nie chce zadziałać – robi się ciekawie.
Oto na co należy zwrócić uwagę:
1. Allow inprocess
we właściwościach profilera zaznacz Allow inprocess. Ta zmiana wymaga niestety późniejszego wykonania restartu SQL
2. TNS_ADMIN
Uruchom CMD, wpisz polecenie SET, wyświetlające zdefiniowane zmienne środowiskowe. Wśród tych zmiennych powinna występować również zmienna TNS_ADMIN wskazująca na lokalizację pliku definiującego lokalizację baz danych Oracle
3. PATH
W podobny sposób zweryfikuj czy katalog w którym jest zainstalowany Oracle oraz podkatalog bin znajdują się w ścieżce. Zależnie od katalogu w jakim zainstalowano Oracle ścieżka ta może się różnić:
Path=D:\applications\Oracle;D:\applications\Oracle\bin;…. and the others
4. Uprawnienia
Upewnij się, że konto MSSQL ma dostęp do katalogów i lokalizacji wskazanych w poprzednich punktach.
2017-02-21
Kiedy wysyłasz wynik zapytania jako załącznik do maila korzystając z procedury sp_send_db_mail dzieją się dwie brzydkie rzeczy:
- do wygenerowanego pliku dołaczany jest tekst np 3 row(s) affected
- między nagłówkiem a danymi pojawia się kreska rozdzielająca te dwa elementy ———————————–
Z pierwszym problemem dosyć łatwo sobie można poradzić. W przekazywanym parametrze @query zamiast samego zapytania, np.:
SELECT id, name FROM database.dbo.table
zapisz
SET NOCOUNT ON;
SELECT id, name FROM database.dbo.table
Gorzej jednak z pomijaniem kreseczek… trzeba użyć sztuczki. Po pierwsze rezygnujemy z generowania nagówka dodając do sp_send_db_mail parametr: @query_result_header = 0
A jak teraz dodać warunek? Zapytanie zmień na UNION dwóch zapytań. Pierwsze z nich wygeneruje to co ma być w załączniku, a drugie zwróci właściwe dane. W efekcie mamy więc:
SET NOCOUNT ON;
SELECT 'id' AS id, 'name' AS name
UNION ALL
SELECT id, name FROM database.dbo.table
2017-02-21
Podczas wysyłania maila z załącznikiem (który jest wynikiem zapytania) pojawiał się bład:
Failed to initialize sqlcmd library with error number -2147024809
O co chodzi? Otóż polecenie wysyłające maila:
EXEC msdb..sp_send_dbmail @profile_name='SQLProfile'
, @recipients = @EmailRecipient
, @subject = @EmailSubject
, @body = @EmailContent
, @body_format = 'HTML'
, @query=@EmailQuery
, @attach_query_result_as_file=1
, @query_attachment_filename = 'Results.csv'
, @query_result_separator = ','
, @from_address = 'sql-team@company.com'
, @reply_to = 'sql-team@company.com'
wykonywało query zdefiniowane tak:
SELECT name from dbo.table
sęk w tym, że w czasie wysyłania maila wcale nie jest to takie jasne w jakiej bazie danych jesteśmy… Wystarczyło zmienić zapytanie na następującą postać żeby zadziałało:
SELECT name from mydatabase.dbo.table