uprawnienia AD

private-property-rightsstruktura AD to żywy organizm, który ewoluuje, ulegając ciągłym modyfikacją – nowi użytkownicy, wycofanie kont… ale również nowi administratorzy i delegacje do poszczególnych gałęzi etc. jak każde środowisko – i to ulega zaśmieceniu. jak każdy bałagan – może to stanowić osłabienie bezpieczeństwa, głównie z powodu jakiś zapomnianych uprawnień. ktoś-gdzieś-kiedyś nadał uprawnienia kontu serwisowemu lub grupie do modyfikacji obiektów, czas leci, a AD nie daje możliwości łatwej weryfikacji nadanych uprawnień. przy złożonej strukturze drzewa, często zostają dziury w postaci niekontrolowanego dostępu na podwyższonych przywilejach.

jak zatem to szybko odczytać? SOA#1 czyli – PowerShellem. podstawowy skrypt jest dość trywialny, ponieważ PS dysponuje możliwością łatwego odpytania się o jednostki organizacyjne oraz odczytanie uprawnień. co więcej – cały kod można uruchomić jako najzwyklejszy user [oczywiście w standardowej konfiguracji]. jedyne, co trzeba na stacji doinstalować to moduł ActiveDirectory [RSAT]. cały problem natomiast, sprowadza się do wyszukania uprawnień, które nie są dziedziczone tylko nadane niezależnie – bo na tym przecież polega delegacja:

$OUList=(Get-ADOrganizationalUnit -Filter *).distinguishedName

foreach( $ou in $OUList) {
    $NonInheritedACEs=(Get-Acl "ad:\$ou").Access| Where-Object {$_.inheritanceflags -eq 'none'}
    Write-Host $ou
    $NonInheritedACEs|group IdentityReference|%{[PSCustomObject]@{'count'=$_.count;'name'=$_.name;'group'=([string]$_.group.ActiveDirectoryRights -join ';')}}
}

to oczywiście zarys, skrypt napisany 'na kolanie’. diabeł leży w szczegółach, więc aby przygotować całe narzędzie trochę walki będzie. a ten diabeł to głównie filtrowanie wyników:

  • w AD jest spora grupa uprawnień niedziedziczonych, nadawanych podczas promocji DC – nazwijmy je 'standardowymi’. mamy więc dwa wyjścia – albo sobie obrobić plik po wypluciu, albo napisać kawałek kodu, który te uprawnienia przefiltruje. może nie jest to super-trudne, ale przyjemne do napisania na pewno też nie jest.
  • z takich 'standardowych uprawnień’, po testach w kilq domenach zauważyłem, że powtarzają się:
1 NT AUTHORITY\ENTERPRISE DOMAIN CONTROLLERS    GenericRead
1 NT AUTHORITY\Authenticated Users              GenericRead
1 NT AUTHORITY\SYSTEM                           GenericAll
1 LOGICUNION\Domain Admins                      GenericAll
4 S-1-5-32-548                                  CreateChild, DeleteChild CreateChild, DeleteChild CreateChild, D...
1 S-1-5-32-550                                  CreateChild, DeleteChild
  • grupy, których SIDy się tutaj nie rozwiązują to Account Operators i Print Operators. warto zwrócić, że to SIDy lokalne a nie domenowe.
  • w niektórych domenach, potrafił te SIDy rozwiązać O_o
  • output powinien być w postaci ładnego obiektu, żeby wyexportować do CSV do dalszej prezentacji i obróbki.
  • get-acl nie ma opcji NIE-rozwiązywania SIDów na nazwy więc trzeba je z powrotem sprawdzać przy porównaniach /:

eN.

 

 

 

jak przeszukiwać Internet przy pomocy PowerShell (;

800px-Mucha-jobdzisiejszy wpis jest przygotowany gościnnie przez Kacpra. Kacper jest specjalistą SCCM i szeroko rozumianej automatyzacji/orkiestracji, co tłumaczy odwołanie się do metod zakrawających na developerkę, gdy UI w postaci formatek dostarczanych przez dostawcę nie wystarczyło. jest to też bardzo ciekawy przykład tego, jak uniwersalny jest PS…

.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.

Nie znasz dnia, ani godziny kiedy może się przydać PowerShell. Szukałem ostatnio lodówki z kostkarką i trafiłem w ten sposób na stronę w http://www.liebherr.aged.com.pl/. Niestety twórca filtra produktów nie przewidzał, że ktoś mógłby szukać lodówki ze wspomnianą kostkarką. Mogłem oczywiście znaleźć sobie jakąś inną stronę czy sklep internetowy. Jednak mój wewnętrzny nerd został podrażniony, nie było już odwrotu. :) Postanowiłem zaprząc PowerShella do tego zadania, jak to mam w zwyczaju. Trzeba było napisać małego crawlera, który znajdzie to czego mi się nie chciało samemu szukać. Efektem postanowienia jest poniższy skrypt:

$rootUris = 'http://www.liebherr.aged.com.pl/produkty/urzadzenia-domowe/side-by-side-i-frenchdoor/', 'http://www.liebherr.aged.com.pl/produkty/urzadzenia-domowe/zamrazarki/', 'http://www.liebherr.aged.com.pl/produkty/urzadzenia-domowe/chlodziarko-zamrazarki/', 'http://www.liebherr.aged.com.pl/produkty/urzadzenia-domowe/chlodziarko-zamrazarki-do-zabudowy/'

$rootUris | ForEach-Object {
    $rootUri = $_
    $response = Invoke-WebRequest -Uri $rootUri
    $links = ($response.Links | Where-Object href -match '.html').href | Sort-Object -Unique

    $urisArray = @()
    $links | %{
        $uriResponse = Invoke-WebRequest -Uri $_
        $urisArray += $uriResponse.RawContent
    }

    Write-Host $rootUri -ForegroundColor Green
    $features = 'Ice Center', 'IceCenter', 'IceMaker'
    $regex = '(?i)<title[^>]*>(.*)</title>'
    $features | ForEach-Object {
        $feature = $_
        
        $urisArray | Where-Object {$_ -match $feature} | ForEach-Object {
            $content = $_
            $result = [Regex]::Matches($content, $regex)
            $result | ForEach-Object {
                "$($feature): $($_.Groups[1].Value)"
            }
        }
        
        #$urisArray | Where-Object {$_ -match $feature} | Select-String -Pattern "<title>.*<\/title>" | %{"$($feature): $($_.Matches.Value)"}
    }
}

O dwóch rzeczach należy wspomnieć. Cmdlet Invoke-WebRequest i wykomentowanej linii na końcu. Invoke-WebRequest wywołuje uczucia ambiwalentne. Z jednej strony ma kilka fajnych funkcjonalności jak np. użyta właściwość Links zwracanego obiektu. Zawiera ona tablicę linków które znajdują się na stronie, więc nie trzeba się bawić w regexy i szukać ich samodzielnie. Jest też kilka innych ciekawych właściwości jak np. Images czy InputFields. niestety Invoke-WebRequest ma też jedną wadę, która może być w pewnych sytuacja dosyć uciążliwa. Mianowicie dosyć słabo sobie radzi z kodowaniem UTF8 bez BOMa. A w zasadzie to w ogóle sobie nie radzi i zwraca po prostu krzaki jeśli na stronie są np. polskie znaki diaktryczne. I niestety nic się nie da z tym zrobić w zasadzie, a przynajmniej mi się nie udało. Jako obejście można skorzystać z klas .NET Net.WebRequest i Net.WebResponse, ale tracimy wtedy opisane wcześniej zalety Invoke-WebRequesta.

Natomiast wykomentowana linia to pierwsza wersja pętli, która znajduje się bezpośrednio nad nią. Korzystając z Select-Stringa nie da się pobrać zawartości znacznika title, bez samego znacznika. Ponownie trzeba się odwołać do klasy .NET Regex, która zwraca grupy dopasowań, a dzięki nim mamy także dostęp do samej zawartości znacznika.

Kacper.

.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.oOo.

eN.

Praca po nocy

Dziś wpis o niskim współczynniku zawartości power shella i twardej administracji, ale mam nadzieje, że nie mniej pomocny.
Po nocy przed monitorem siedzi każdy z nas, może nie z taką częstotliwością jak na studiach #goodoldtimes, ale przynajmniej okna serwisowe wypadają gdy słońce już dawno zaszło. Kiedyś, pisząc kolejne projekty na zaliczenie zwracałem uwagę na zbyt jasne oświetlenie monitora, szczególnie tła kartki w Wordzie. W nowych Windowsach, (tak gdzieś od 7) nie mogłem znaleźć tego ustawienia, a tu z pomocą przychodzi dedykowany program F.lux.
https://justgetflux.com/
Narzędzie automatycznie dostosowuje temperaturę kolorów monitora po zachodzie słońca. Sprawdziłem wczoraj w nocy – działa perfekcyjnie. Małe, proste, łatwo w razie czego wyłączyć na chwilę.
Polecam.

Dodatkowo jak już siedzimy po nocy, można zajrzeć na stronę o zdrowym śnie, sygnowaną przez Uniwersytet Harwarda: http://healthysleep.med.harvard.edu/portal/.

nowości w PS5 – remote copy

Windows_PowerShell_iconbyło na WGUiSW

IMHO jednym z najważniejszych rozszerzeń, bo przydatnych w codziennej pracy, jakie pojawiły się w PowerShell 5 jest możliwość kopiowania plików via winRM – coś aka SCP. SMB ma swoje wymagania i raczej nie otwiera się portów na zewnątrz dla tego protokołu. winRM pozwala szyfrowanym kanałem przesłać plik uzupełniając możliwości zdalnej administracji.

wymaganiem jest oczywiście, aby po obu stronach był PS5 [WMF5], czyli niestety, jeszcze przez kilka miesięcy raczej rozwiązanie laboratoryjne, ponieważ WMF5 jest cały czas jako production preview. instalowałem testowo na w2k12R2 i w2k8R2 – i na tym drugim, niestety ze skutkiem śmiertelnym dla PS5 [bez paniki, nie debugowałem problemu, ale na pewno 'don’t do it on production’ jak mawiają rodzice].

plik kopiuje się podając sesję zdalną, a więc najpierw trzeba ją założyć. niestety nie jest obsługiwane kopiowane do wielu sesji na raz ):

$s=new-PSSession server01.wfiles.lab
copy-item -path c:\temp\filetocopy.txt -toSession $s -destination c:\temp

obsługiwane jest również kopiowanie Z serwera przy pomocy 'fromSession’. kopiowane 'proxy’ czyli podając równocześnie 'do’ i 'z’ nie zadziała:

PS C:\Users\nexor> Copy-Item -FromSession $fromSession -Path c:\temp\* -ToSession $toSession -Destination c:\temp
Copy-Item : '-FromSession' and '-ToSession' are mutually exclusive and cannot be specified at the same time.
At line:1 char:1
+ Copy-Item -FromSession $fromSession -Path c:\temp\* -ToSession $toSes ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (Microsoft.Power...namicParameters:CopyItemDynamicParameters) [Copy-Ite
   m], ArgumentException
    + FullyQualifiedErrorId : InvalidInput,Microsoft.PowerShell.Commands.CopyItemCommand

niewątpliwie funkcjonalność, dla której warto będzie na serwerach podnieść wersję WMF, jak już będzie wersja finalna.

eN.

 

Exchange – uprawnienia do kalendarzy zasobów

exchange-logoogólnie

prosty scenariusz: trzeba założyć zasób, reprezentujący samochód firmowy tak, aby ludzie mogli go sobie rezerwować. następnie chcemy aby wszyscy widzieli kto go wypożyczył i dokąd zabrał. standardowo większość informacji jest ukryta i widać tylko ogólny wpis.

w tym celu należy nadać uprawnienia do kalendarza nie jest trudno i jest sporo linków, które szybko wskażą, że można to zrobić poleceniem:

Set-MailboxFolderPermission "roomResource@wfiles.pl:\calendar" -User default -AccessRights reviewer

… ale:

  • po pierwsze to nie zawsze zadziała (w Polsce można uznać, że prawie nigdy)
  • są bardziej złożone scenariusze. no i co daje 'reviewer’?? dla tego warto wiedzieć więcej – np. jakie inne uprawnienia można nadać
  • czemu nadal nie ma wszystkich informacji
  • a co przy jeszcze bardziej wymyślnych wymaganiach dotyczących automatyki? jak jeszcze może 'reagować’ taki obiekt na rezerwację?

lokalizacja

czemu w PL nie zadziała? ponieważ 'calendar’ to nazwa katalogu, a ta jest zlokalizowana. żeby było śmieszniej nazwa będzie zależna od… ustawień przeglądarki w momencie tworzenia obiektu zasobu (użytkownikom definiuje się kraj). sweet. ponieważ mam główną przeglądarkę ustawiona na en-US, żeby nie oglądać raniących w oczy auto-tłumaczeń technetowych czy portalu office365 w którym ciężko się połapać, część obiektów ma 'calendar’ a część 'kalendarz’. zakładając z command line zawsze tworzy 'calendar’ pomimo polskich regionalsów, więc mniemam, że ten sposób jest bardziej deterministyczny (ale trzeba by porobić więcej testów na różnie zlokalizowanych systemach).

czyli zapis ścieżki do konkretnego folderu to „roomResource@wfiles.pl:\kalendarz” . i znów – tyle dość łatwo i szybko można wyszperać na forach… ale pozostaje pytanie – jak wylistować wszystkie katalogi?? skoro jest kalendarz, to pewnie są jakieś inne foldery i może da się z nimi coś zrobić? i jak sprawdzić czy to jest 'calendar’ czy 'kalendarz’? ale najpierw…

uprawnienia

standardowo, po utworzeniu zasobu sali lub ekwipunq jedyne co widać w kalendarzu to 'busy’. equipmentMBXdef

można to zmienić i umożliwić bardziej pełny widok nadając uprawnienia LimitedDetails lub Reviewer (pełna lista uprawnień tutaj). różnica jest dość poważna. ograniczone detale pozwolą na zobaczenie organizatora i lokalizacji ale nie pozwolą otworzyć zdarzenia ze względu na brak uprawnień:

equipmentMBXrevequipementMBXnoaccnadanie uprawnień podglądacza (; pozwoli otworzyć wpis w kalendarzu i w pełni mu się przyjrzeć:

equipmentMBXdetaa gdzie informacje??

na pierwszy rzut oka może wygląda dobrze, ale ktoś choć trochę bardziej spostrzegawczy zauważy, że pole tematu oraz szczegółowe informacje chyba nie dają pełnych informacji. i faktycznie – standardowo, założenie jest takie: ktoś wynajmuje salę, wysyła zaproszenie, więc w tym zaproszeniu umieszcza informacje o czym będzie rozmowa, pewnie agendę, może jakieś materiały dodatkowe itd. zasób sali dostaje to samo zaproszenie co każdy inny – a to byłby niekontrolowany wyciek informacji. nie byłoby miło, gdyby cała firma wiedziała, że właśnie dyrektorzy spotykają się, np. żeby omówić zwolnienia pracowników… dla tego standardowe opcje są ustawione restrykcyjnie i wycinają wszystkie informacje.

są jednak scenariusze, w których niektóre osoby muszą wiedzieć więcej – np. dział logistyki musi wiedzieć gdzie jest samochód i po co. wtedy trzeba wykonać następujące operacje:

  • nadać ludzikom uprawnienia 'limitedDetails’ żeby widzieli 'kto’ ale niewiele więcej (set-MailboxFolderPermission)
  • nadać wybrańcom uprawnienia 'reviewer’ żeby mogli wejść i zobaczyć detale (add-MailboxFolderPermission)
  • no i skonfigurować zasób tak, żeby te informacje przyjmował a nie wycinał. (set-CalendarProcessing)

zobaczmy jakie zachowania można dla zasobu ustawić:

C:\...ive\_scriptz :))o- Get-CalendarProcessing -Identity roomResource@wfiles.pl|fl *


PSComputerName                      : outlook.office365.com
RunspaceId                          : 7518df28-1a3e-49e2-bc1b-6af5eb66bd48
PSShowComputerName                  : False
AutomateProcessing                  : AutoAccept
AllowConflicts                      : False
BookingWindowInDays                 : 180
MaximumDurationInMinutes            : 1440
AllowRecurringMeetings              : True
EnforceSchedulingHorizon            : True
ScheduleOnlyDuringWorkHours         : False
ConflictPercentageAllowed           : 0
MaximumConflictInstances            : 0
ForwardRequestsToDelegates          : True
DeleteAttachments                   : True
DeleteComments                      : False
RemovePrivateProperty               : True
DeleteSubject                       : False
AddOrganizerToSubject               : True
DeleteNonCalendarItems              : True
TentativePendingApproval            : True
EnableResponseDetails               : True
OrganizerInfo                       : True
ResourceDelegates                   : {}
RequestOutOfPolicy                  : {}
AllRequestOutOfPolicy               : False
BookInPolicy                        : {}
AllBookInPolicy                     : True
RequestInPolicy                     : {}
AllRequestInPolicy                  : False
AddAdditionalResponse               : False
AdditionalResponse                  :
RemoveOldMeetingMessages            : True
AddNewRequestsTentatively           : True
ProcessExternalMeetingMessages      : False
RemoveForwardedMeetingNotifications : False
MailboxOwnerId                      : Skoda
Identity                            : Skoda
IsValid                             : True
ObjectState                         : Changed

wszystkich nie ma sensu tłumaczyć, można przeczytać na technecie, nas interesują konkretnie DeleteSubject, DeleteComents. jak widać można również pozwolić na załączniki, kontrolować czy zatwierdzanie jest automatyczne czy wymaga ręcznego potwierdzenia, czy w polu tematu dodawana jest nazwa użytkownika… i inne. przykładowa konfiguracja zasobu:

set-MailboxFolderPermission 'roomResource@wfiles.pl:\kalendarz' -User default -AccessRights limitedDetails
add-MailboxFolderPermission 'roomResource@wfiles.pl:\kalendarz' -User logistics@wfiles.pl -AccessRights reviewer
Set-CalendarProcessing -Identity roomResource@wfiles.pl -DeleteComments $false -DeleteSubject $false

i w takim przypadq dział logistyki może zobaczyć takie krzaczki…

equipmentMBXfulllista folderów

na koniec powrócę do listy folderów. tu niestety niespodzianka: nie da się wylistować folderów dla zasobu. ponieważ zasób jest skrzynką… ale równocześnie nią nie jest. jest – i te foldery są, ale nie jest – bo tak twierdzi system. poniżej mała zabawa – wylistowanie folderów dla regularnego mailboxa, próba wylistowania dla zasobu i dowód, że jednak wszystkie foldery są…

C:\...ive\_scriptz :))o- Get-MailboxFolder -Identity nexor@wfiles.pl -GetChildren

Name                 FolderPath             HasSubfolders
----                 ----------             -------------
Conversation History {Conversation History} False
Dziennik             {Dziennik}             False
Elementy usunięte    {Elementy usunięte}    True
Elementy wysłane     {Elementy wysłane}     False
Kalendarz            {Kalendarz}            True
Kontakty             {Kontakty}             True
Mało istotne         {Mało istotne}         False
Notatki              {Notatki}              False
RSS Feeds            {RSS Feeds}            False
Skrzynka nadawcza    {Skrzynka nadawcza}    False
Skrzynka odbiorcza   {Skrzynka odbiorcza}   True
Sync Issues          {Sync Issues}          True
Wersje robocze       {Wersje robocze}       False
Wiadomości-śmieci    {Wiadomości-śmieci}    False
Zadania              {Zadania}              False


C:\...ive\_scriptz :))o- Get-MailboxFolder -Identity roomResource@wfiles.pl -GetChildren
The specified mailbox "testeq2@netwise.pl" doesn't exist.
    + CategoryInfo          : NotSpecified: (:) [Get-MailboxFolder], ManagementObjectNotFoundException
    + FullyQualifiedErrorId : [Server=VI1PR07MB1375,RequestId=2d356745-d5fe-4ff8-8deb-314d0a8e578b,TimeStamp=2015-11-0
   5 11:40:17] [FailureCategory=Cmdlet-ManagementObjectNotFoundException] 6C1FD1AF,Microsoft.Exchange.Management.Stor
  eTasks.GetMailboxFolder
    + PSComputerName        : outlook.office365.com

C:\...ive\_scriptz :))o- Get-MailboxFolderPermission 'roomResource@wfiles.pl:\inbox'

FolderName           User                 AccessRights
----------           ----                 ------------
Inbox                Default              {None}
Inbox                Anonymous            {None}

przy czym normalny user ma nazwy katalogów po polsq bo zakładając tak miał zdefiniowaną licencję, a zasób po ang. bo był zakładany z linii poleceń, a zasoby licencji nie posiadają. wykorzystanie 'get-mailboxfolderpermission’ w połączeniu z intuicją to jedyny sposób jaki znalazłem, żeby sprawdzić czy dany folder istnieje dla zasobu…

eN.

 

75. spotkanie WGUiSW

big_wguiswdziś pierwszy wtorek, więc zgodnie ze świecką tradycją – WGUiSW. będą dwie sesje.

  • moja, o zmianach w PowerShell 5.o
  • oraz Leszka Betlińskiego, o tajemniczo brzmiącym tytule 'Agent Ci pomoże’

jak zwykle w eMeSach oraz online (:

eN.