Pokazywanie postów oznaczonych etykietą PowerShell. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą PowerShell. Pokaż wszystkie posty

23 stycznia 2022

Kolekcja skryptów Powershell

Przez wiele lat moje skrypty ułatwiające konfigurację czy też dokumentowanie organizacji serwerów Exchange wisiały w galerii Technet i mogę powiedzieć z dumą, że większość z nich było pobieranych ponad 1000 razy i doczekały się wielu pozytywnych opinii. Niestety, galeria została w zeszłym roku zamknięta, co nie oznacza jednak, że skrypty zniknęły z internetu. Przeniosłem je na swoje konto GitHub, a ostatnio nawet zacząłem je nieco odświeżać, tak żeby np. działały poprawnie z serwerami Exchange 2019.  Na tym samym koncie w trakcie pandemii pojawiły się również skrypty, pomagające zarządzać środowiskami Office 365 w edukacji, ale oczywiście można je również wykorzystać w tenantach komercyjnych.

Dla przypomnienia przedstawiam poniżej listę skryptów dla edukacji:

  1. addusersfromfile.ps1 - opisany w artykule na moim blogu
  2. bulkpasswordreset.ps1 - opisany w artykule na moim blogu
  3. zmianaDisplayName.ps1 - opisany w artykule na moim blogu
A tutaj lista skryptów dla Exchange:
  1. set-allvdirs.ps1 - skrypt ustawia wszystkie (lub tylko wybrane przez nas) wirtualne katalogi wszystkich serwerów Exchange lub tylko lokalnego oraz SCP usługi autodiscover.
  2. get-allvdirs.ps1 - sprawdza i zapisuje w pliku informacje o wszystkich wirtualnych katalogach na serwerach Exchange w organizacji.
  3. get-ExDocs.ps1 - zapisuje w plikach parametry konfiguracyjne wszystkich usług Exchange naszej organizacji.
  4. remove-oldaliases.ps1 - kasuje dla wszystkich odbiorców poczty wybrany alias
  5. reenableExServices.ps1 - W przypadku niepoprawnej instalacji poprawki Exchange, może nastąpić sytuacja, gdy usługi Exchange pozostają w stanie disabled. Skrypt naprawia taki problem.
  6. list-mobiledevsforallmailboxes.ps1 - prosty skrypt do wyświetlania listy urządzeń mobilnych, skonfigurowanych dla użytkowników Exchange.

28 sierpnia 2021

CLM - Ograniczanie możliwości Powershell w środowisku firmowym

Powershell jest moim ulubionym językiem skryptowym, bardzo popularny na platformie Windows i w chmurze, stopniowo zadomawia się również w środowiskach Linux, stał się również zamiennikiem powłoki systemu operacyjnego Windows. Taka popularność rodzi obawy przed możliwymi zagrożeniami, więc warto zastanowić się jak można poprawić bezpieczeństwo środowiska? Od wersji 3.0 wprowadzono w Powershell możliwość włączenia trybu Constrained Language Mode (CLM), co powoduje znaczące ograniczenie możliwości wywołania bardziej zaawansowanych mechanizmów języka (bardziej szczegółowy opis ograniczeń można znaleźć w artykule https://devblogs.microsoft.com/powershell/powershell-constrained-language-mode).

Cmdlety wykonują się poprawnie, jednak przy wywołaniu skryptu możemy zobaczyć komunikat:

Cannot invoke method. Method invocation is supported only on core types in this language mode.
Czyli włączenie CLM, będzie skutkowało koniecznością zweryfikowania wszystkich skryptów, które są wykonywane w tak chronionym kontekście, a nawet zmodyfikowania pliku profilowego.
No dobrze, ale dobrze jest wiedzieć, jak włączyć CLM w naszym środowisku. W ramach pojedynczej sesji Powershell wystarczy wykonać komendę:

$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"

Oczywiście, jeżeli uruchomimy drugą sesję Powershell to będzie ona działać w trybie standardowym. Możemy również ponownie zmienić tryb pracy na pełny komendą

$ExecutionContext.SessionState.LanguageMode = "FullLanguage"

Możemy również ustawić zmienną środowiskową __PSLockDownPolicy na wartość 4.  Jednak zalecanym rozwiązaniem w środowisku domenowym Active Directory jest użycie polis GPO, włączając odpowiednie polisy - AppLocker dla komputerów Windows 7 lub nowszych, ewentualnie Windows Defender Application Control dla Windows 10.

Przykładowo, dla applockera tworzymy polisę, w której definiujemy reguły dla skryptów (rysunek poniżej), nie możemy również zapomnieć o wymuszeniu stosowania polisy (kolejny rysunek).





















Wymuszenie konfiguracji komputera przez GPO jest trudne do obejścia, nawet dla osoby mającej uprawnienia administracyjne. Warto w takim przypadku spojrzeć na szczegóły polisy opisującej konfigurację applockera dla skryptów. Przy włączonym wymuszeniu stosowania polisy na naszym komputerze, będzie działać tryb CLM we wszystkich lokalizacjach oprócz dopuszczonych przez polisę, gdzie będzie działać pełny tryb języka. Przy domyślnych regułach lokalni administratorzy mogą uruchamiać skrypty bez ograniczeń, a pozostali użytkownicy tylko z folderów Windows i Program Files, ale jeżeli domyślne reguły zostały zmienione, to dobrze jest to sprawdzić, chociażby podglądając ustawienia polisy w konsoli Group Policy Management, jak pokazuje rysunek poniżej.



30 sierpnia 2020

Zmiana display name w Office 365

Jednym z pytań, które ostatnio się pojawia, to zmiana sortowania użytkowników w zespołach. Niestety domyślnie pole Display Name, które jest  wykorzystywane w sortowaniu użytkowników, jest tworzone na podstawie pól Imię i Nazwisko. Jednak administrator może zmienić wartość tego pola bez wpływu na działanie systemu. Można edytować każdego użytkownika indywidualnie, ale oczywiście prościej to zrobić z poziomu powershell. W tym celu możemy użyć pliku csv, użytego do importu danych uczniów i nauczycieli, lub dowolnego innego pliku csv, np. lista użytkowników wyeksportowana z panelu administracyjnego.


W tym celu możemy użyć prostego skryptu, który zaimportuje listę użytkowników z pliku i utworzy pole displayname z połączenia wartości pól z imieniem i nazwiskiem. W tym celu powinniśmy poniższy kod zapisać jako plik z rozszerzeniem ps1 (na przykład zmiana.ps1 w katalogu c:\Scripts) i uruchomić go z Powershella (pamiętajmy, żeby wcześniej zainstalować moduł MSOnline przy pomocy komendy install-module MSOnline jako administrator):

Import-Module Msonline

Connect-MsolService

#

# nagłówek pliku csv -> UserPrincipalName,Imie,Nazwisko

# jeżeli kolumny rozdzielone są znakiem ";" zamiast "," należy użyć przy imporcie atrybutu -Delimeter (import-csv domyślnie szuka ",")

#

$AllStudents = Import-CSV D:\Scripts\uczniowie.csv -Delimiter ";"

ForEach ($student in $AllStudents)

{

$DisplayName = $student.Nazwisko+" "+$student.Imie

$currentstudent = get-MsolUser -UserPrincipalName $student.UserPrincipalName

set-MsolUser -ObjectId $currentstudent.ObjectId -Displayname $DisplayName

}

Kod skryptu dostępny również na moim githubie. Możemy również bezpośrednio przetworzyć atrybuty obiektów w naszej organizacji, bez użycia pliku csv wykonując nieco zmodyfikowany skrypt:
Import-MsolService
Connect-MsolService

$Allusers = get-MsolUSer

ForEach ($user in $Allusers)
{
$DisplayName = $user.LastName+" "+$user.FirstName
Set-MsolUser -ObjectId $user.ObjectId -Displayname $DisplayName
}

Jeżeli pole DisplayName chcemy uzupełnić o dodatkowy atrybut, np. rocznik ucznia, to w pliku csv musimy dodać jeszcze jedną kolumnę, o nazwie np. Rok i zmienić w skrypcie wiersz, tworzący pole:

$DisplayName = $student.Nazwisko+" "+$student.Imie + " " + $student.Rok

Oczywiście najpierw powinniśmy zainstalować odpowiedni moduł do zarządzania Office 365. O modułach niezbędnych dla Office 365 pisałem już wcześniej na swoim blogu:

26 czerwca 2020

Blokowanie Teams na wakacje

Ciekawy problem pojawił się ostatnio na jednej z grup dyskusyjnych - jak zablokować uczniom Teams na wakacje. Oczywiście można to zrobić na kilka sposobów, ale jak dla mnie najlepsza jest akcja z poziomu powershell. Standardowy moduł MSOnline pozwala na elastyczne zarządzanie serwisami w ramach poszczególnych pakietów licencji, o czym możemy przeczytać w dokumentacji
Jednak oczywiście diabeł tkwi w szczegółach - czyli co powinniśmy wyłaczyć? Tak więc po kolei biorę się do działania. Po połączeniu się w sesji powershell (najlepiej w wersji 5.1, bo niestety moduł MSOnline jest dosyć stary i nie działa w wersji Core) do naszej organizacji sprawdzamy jakie pakiety licencji mamy (obrazek poniżej):













Jeżeli chcemy zablokować wybrane usługi w licencji dla ucznia, to warto sprawdzić jakie nazwy są używane dla poszczególnych usług (kolejny obrazek):



























Teraz możemy sobie zdefiniować opcjonalny plan licencyjny dla ucznia, z wyłączeniem licencji Teams. Zgodnie z artykułem pomocy technicznej linkowanym wcześniej w tym poście tworzymy odpowiednią paczkę licencyjną:
$LO = New-MsolLicenseOptions -AccountSkuId "konsagedu:STANDARDWOFFPACK_STUDENT" -DisabledPlans "Teams1"
Teraz możemy ja przypisać do konkretnego ucznia lub grupy uczniów jak pokazuje kolejny obrazek:
Set-MsolUserLicense -UserPrincipalName Adaa@konsagedu.onmicrosoft.com -LicenseOptions $LO





W pakiecie opcji licencyjnych możemy umieścić kilka dodatkowych opcji do wykluczenia. Jednak należy to dobrze rozważyć, żeby nie zablokować zbyt wielu elementów, uniemożliwiając całkowicie korzystanie z Office 365.

28 marca 2020

Office 365 - problemy ze spamem

Wysyłając pocztę ze skrzynek na Office 365 czasem ze zdziwieniem orientujemy się, że trafia ona do spamu. Niestety, pomagając administratorowi opublikować niezbędne dla Exchange Online rekordy, Microsoft nadal podaje tylko 3 rekordy - MX, SPF i autodiscover. Już jakiś czas temu publikowałem kilka postów o dodatkowych metodach zabezpieczania poczty - DKIM oraz DMARC. Od tego czasu zdecydowana większość firm używa już tych mechanizmów. Warto poświęcić kilka minut, żeby skonfigurować je dla swojej organizacji Office 365. O ile konfiguracja DMARC to tylko dodanie rekordu do DNS (przynajmniej na początku), to konfiguracja DKIM wymaga jeszcze włączenia na poziomie Exchange Online. W artykule https://pepugmaster.blogspot.com/2016/03/walka-ze-spamem-spf-dkim-dmarc.html opisałem konfigurację w Office 365, jednak ostatnio zaważyłem, że dla własnych domen, obsługiwanych w Office 365 możliwość włączenia w webowym panelu administracyjnym, zarówno Exchange Admin Center, jak i https://protection.office.com/dkim została ukryta.
Funkcjonalność nie jest zablokowana, ale jak wiele zaawansowanych funkcji dostępna tylko w powershell. Wystarczy z poziomu modułu administracyjnego Exchange Online wykonać komendę:
new-DkimSigningConfig -Identity -KeySize 2048 -Enabled $true
Jeżeli w DNS dla naszej domeny nie dodaliśmy niezbędnych rekordów, funkcjonalność zostanie skonfigurowana, ale nie będzie włączona, o czym zostaniemy poinformowani odpowiednim komunikatem:




Jeżeli uzupełnimy/poprawimy rekordy, możemy włączyć zabezpieczenie domeny komendą:
set-DkimSigningConfig -Identity lab.pepug.org -Enabled $true.
I nasza poczta będzie bardziej wiarygodna.

25 marca 2020

Podstawy automatyzacji w Office 365 dla EDU

Kontynuując omawianie tematów poruszanych na grupach dyskusyjnych dotyczących pytań i problemów związanych z wdrażaniem Office 365 w Edukacji, chciałem tym razem poruszyć temat automatyzacji niektórych zadań przy pomocy Powershella. Temat przygotowania swojego komputera do zarządzania środowiskiem Office 365 poruszałem na tym blogu już kilkakrotnie, więc żeby się nie powtarzać zachęcam do lektury tych artykułów:
Oczywiście moduły się zmieniają, pojawiają się nowe (np. całkowicie odświerzony moduł dla Exchange Online), inne wychodzą z użycia. Warto więc co jakiś czas sprawdzać nowości w tym zakresie czy chociażby co jakiś czas uruchomić komendę update-module.
Kilka typowych wyzwań, przed którym staje administrator szkolnej instancji Office 365 to:
  1. Zakładanie użytkowników i przypisywanie im licencji
  2. Resetowanie haseł użytkownikom.
  3. Tworzenie zespołów Teams.
  4.  Przypisywanie użytkownikom polityk.
Przedstawię tu kilka przykładów, dla powyższych zagadnień:

1. Zakładanie użytkowników i przypisywanie im licencji

Jak założyć wielu użytkowników, np wszystkich nauczycieli lub wszystkich uczniów? Najlepiej byłoby (ze względu na stan epidemii i konieczność wdrożenia w jak najkrótszym czasie) utworzyć dla nich konta skryptem i dodatkowo wysłać im loginy i hasła początkowe na już znany adres. Po pierwsze potrzebujemy plik csv, z listą użytkowników. Warto pamiętać, że powershell domyślnie akceptuje "," jako znak przystankowy, a dla polskich ustawień regionalnych Microsoft Excel najczęściej tworzy taki plik z polami rozdzielonymi ";" - jest to zaznaczone w przykładowym skrypcie. Żeby konto miało od razu przypisaną licencję, dobrze jest to również załatwić w naszym skrypcie. W pierwszej kolejności potrzebujemy się zalogować do naszej instancji Office 365 (tzw. tenanta) i sprawdzić identyfikatory licencji (niestety w każdej instancji jest dodatkowo doklejany id tenanta, czy mamy taką zbitkę - konsagedu:STANDARDWOFFPACK_STUDENT. W tym wypadku konsagedu jest identyfkatorem mojej testowej organizacji Office 365 (jak widać na obrazku).






Jaką wartość wpisać do skryptu sprawdzamy komendą Get-MsolAccountSku. Standardowo powinniśmy mieć przypisaną do naszej organizacji licencję A1 dla nauczycieli i A1 dla uczniów (chyba że aktywowaliśmy inne licencje np. do testów). Oczywiście licencje możemy przypisać później, po utworzeniu grup dla poszczególnych klas i nauczycieli. Przypisanie licencji do grup jest realizowane bardzo prosto w portalu administracyjnym Azure AD w zakładce licencje.
Następnie listę nauczycieli/uczniów wyeksportowaną z zewnętrznego źródła importujemy z pliku csv. Plik powinniśmy uzupełnić o kolumnę UserPrincipalName (nie może być w niej polskich znaków), czyli nazwę logowania użytkownika do naszej organizacji Office. Ze względu na RODO dla uczniów nie powinno to być ImieNazwisko, ponieważ w połączeniu ze szkolną domeną stanowi już dane osobowe. Może to być np. identyfikator z dziennika elektronicznego. Jeżeli chcemy wysłać informacje mailem to musimy również wypełnić kolumnę email, która będzie przypisywana do pola Alternatywny Email w Azure AD. Warto również pamiętać, że jeżeli chcemy wysyłać maile ze skryptu, to musimy się uwierzytelnić i użyć portu 587. Skrypt będzie wyglądał np. tak:

# Podajemy poświadczenia administracyjne i łączymy się z chmurą
$cred = get-credential
Connect-MsolService -Credential $cred

# podajemy nazwę licencji dla ucznia
$StudentsLicense = 'konsagedu:STANDARDWOFFPACK_STUDENT'

# importujemy listę uczniów z pliku csv w postaci
# UserPrincipalName;DisplayName;Imie;Nazwisko;email;telefon
# Musimy wskazać znak rozdzielający, jeżeli plik csv ma kolumny rozdzielone
# innym znakiem niż ,

$AllOffice365Students = Import-CSV D:\Scripts\naglowek.csv -Delimiter ";"

# dla każdego wiersza z pliku csv wykonujemy akcję
foreach ($Student in $AllOffice365Students) {
    # tworzymy nowe konto w usłudze Office 365
    $O365student = New-MsolUser -UserPrincipalName $Student.UserPrincipalName `
         -AlternateEmailAddresses $Student.email -DisplayName $Student.DisplayName `
         -FirstName $Student.Imie -LastName $Student.Nazwisko -mobilePhone $Student.telefon `
         -UsageLocation PL -PreferredLanguage PL-pl -PasswordNeverExpires $true `
         -StrongPasswordRequired $true
    # przypisujemy licencję
    Set-MsolUserLicense -UserPrincipalName $Student.UserPrincipalName `
         -AddLicenses $Studentslicense

    # pobieramy dane po utworzeniu konta
    $mail = $Student.email
    $pwd = $O365student.Password
    $stu = $Student.UserPrincipalName
    $body = "Utworzono konto w systemie Office 365 o nazwie $stu Haslo tymczasowe: $Pwd"
    # wysyłamy maila z hasłem na alternatywny adres uzytkownika
    Send-MailMessage  -SmtpServer smtp.office365.com -usessl -Credential $cred `
          -Port 587 -To "$mail" -From "admin@konsagedu.onmicrosoft.com" `
          -Subject "Office 365 - nowe konto" -Body $body -Encoding UTF8 -BodyAsHtml
}
Kod skryptu dostępny na moim githubie.
Id licencji i konto administratora  oczywiście w skrypcie jest powiązanie z moją organizacją testową. Uwaga. Jeżeli dla administratora włączyliśmy uwierzytelnianie wieloskładnikowe (MFA), to do wysłania maila musimy użyć hasła aplikacyjnego, a nie tego, którym się normalnie logujemy. UWAGA: od początku marca domyślnie organizacje Office 365 mają włączone tzw. domyślne ustawienia zabezpieczeń, które wymuszają MFA. Jeżeli uznamy, że jest to dla uczniów i nauczycieli zbyt uciążliwe możemy to wyłączyć w portalu administracyjnym Azure AD.

2. Resetowanie haseł użytkownikom

W przypadku sytuacji, gdy musimy zresetować hasło grupie użytkowników, możemy postąpić bardzo podobnie - zaimportować listę użytkowników z pliku csv, tym razem wystarczy nam nazwa użytkownika czyli UserPrincipalName i alternatywny adres mailowy. Czyli postępujemy podobnie:

# Podajemy poświadczenia administracyjne i łączymy się z chmurą
$cred = get-credential
Connect-MsolService -Credential $cred

$Pwd = 123zxcASD
# importujemy listę uczniów z pliku csv w postaci
# UPN,email

$AllOffice365Students = Import-CSV D:\Scripts\naglowek.csv

# dla każdego wiersza z pliku csv wykonujemy akcję
foreach ($Student in $AllOffice365Students) {
    Set-MsolUserPassword -UserPrincipalName $Student.UPN -NewPassword $Pwd `
      -ForceChangePassword $True

    # pobieramy dane po utworzeniu konta
    $mail = $Student.email
    $stu = $Student.UPN
    $body = "Zresetowano haslo w systemie Office 365. Haslo tymczasowe: $Pwd"

    # wysyłamy maila z hasłem na alternatywny adres uzytkownika
    Send-MailMessage  -SmtpServer smtp.office365.com -usessl -Credential $cred `
-Port 587 -To "$mail" -From "admin@konsagedu.onmicrosoft.com" `
-Subject "Office 365 - zmiana hasla" -Body $body -BodyAsHtml
}
Kod skryptu dostepny na moim githubie.

3. Tworzenie zespołów Teams

Jeżeli chodzi o zakładanie zespołów w Teams. to już niedługo będzie to można zrobić z użyciem modułu MicrosoftTeams, jednak jak na razie cmdlet New-Team nie obsługuje atrybutu Template, który pozwala nam wybrać szablon klasy lub personelu. Teraz możemy to zrobić z użyciem Graph API. Przykładowy skrypt udostępnili koledzy na githubie grupy Microsoft 365  User Group Poland - https://github.com/Microsoft-365-User-Group-Poland/Skrypty

4. Przypisywanie użytkownikom polityk

Wiele ustawień zarówno bezpieczeństwa jak i funkcjonalnych można przypisać wielu użytkownikom Office 365 poprzez utworzenie i przypisanie odpowiednik polityk (określanych również jako polisy). Przypisywanie użytkownikom wszystkich przydatnych polityk to temat na osobny artykuł - w zależności od obszaru funkcjonalnego, dla którego polityki mają być przypisywane, to konfigurujemy je z użyciem różnych modułów:

  • polityki związane z hasłami - moduł AzureAD.
  • polityki związane ze skrzynką pocztową - moduł Exchange Online (lub nowy moduł ExchangeOnlineManagement).
  • polityki dotyczące Teams - moduł MicrosoftTeams (chociaż niektóre polityki są konfigurowane w module Skype for Business Online), etc.
Myślę, że ciekawym przypadkiem przypisywania polityk może być ograniczanie uprawnień uczniom w Teams, poprzez tzw. Policy Packages, czyli pakiety polityk. Jak sama nazwa wskazuje, pakiet polityk opisuje grupę zasad zarówno dla komunikacji w ramach chatów, spotkań, używania aplikacji, połączeń głosowych - słowem wszystkich obszarów współpracy w ramach aplikacji Micosoft Teams. W celu zaaplikowania pakietu dla wszystkich uczniów w jednym kroku, musimy odfiltrować konta z przypisaną licencją ucznia.
W tym celu dla odmiany użyję modułu AzureAD. Wyświetlę licencje dostępne w moim tenancie EDU i odfiltruję użytkowników z przypisaną taką licencją. Id licencji sprawdzę komendą get-AzureAdSubscribedSku:





Mając ID mogę użyć filtra przygotowanego z jego pomocą
$students = Get-AzureADUser -All $true | Where-Object {($_.assignedLicenses).SkuId `
  -contains "314c4481-f395-4525-be8b-2ec4bb1e9d91"}.
Teraz jeszcze tylko sprawdzę, jakie pakiety polis są dostępne w moim tenancie












I można już uruchomić w pętli przypisanie odpowiedniej paczki (np. dla licealistów będzie to Education_SecondaryStudent).
foreach ($student in $students) {Grant-CsUserPolicyPackage -Identity $student.UserPrincipalName `
   -PackageName Education_SecondaryStudent }

Taką samą pętlą możemy sprawdzić, czy polisy package został przypisany poprawnie:
foreach ($student in $students) {Get-CsUserPolicyPackage -Identity $student.UserPrincipalName }
Oczywiście ustawienia polis w ramach pakietów możemy modyfikować bądź też tworzyć własne.
UPDATE:
W dokumentacji Microsoft Teams dla EDU pojawił się rozbudowany artykuł z przykładami przypisywania polis, odpinania polis i powiązanych operacji. Warto przeczytać jako uzupełnienie tego artykułu.

26 stycznia 2020

Response Groups Service - agenci widma

Jedną z ciekawszych funkcjonalności dla połączeń głosowych, istniejących w Skype for Business (która zresztą była dostępna już w OCS) jest Response Group Service. W RGS definiowane są kolejki, do których przypisujemy grupy agentów, do których kierowane są rozmowy. Niestety, wyłączenie użytkownika w SfB nie usuwa agenta z grupy (jest w niej zapisywany adres SIP URI agenta), co oczywiście może powodować problemy, przy próbie zestawienia rozmowy z takim kontem. Podobnie można wyłączyć użytkownikowi Enterprise Voice, jednak to również nie usuwa agenta z grupy, co również będzie powodowało nieoczekiwane problemy w działaniu usługi.
Jak możemy zweryfikować, czy w naszych grupach agentów znajdują się niepoprawne obiekty? Ciekawy artykuł i skrypt do wykrywania takich agentów zombie udostępnił na swoim blogu Greig Sheridan. Pomysł oparł na zweryfikowaniu istnienia zdarzeń typu Warning o numerach 31137 lub 31137 w Event Logu.  Zdarzenia te ostrzegają właśnie o znalezieniu agenta z wyłączonym EV lub nieistniejącego w AD. W zależności od użytego przełącznika możemy wykonać raport lub od razu usunąć niepoprawnych agentów.
Jednak przy dużej ilości serwerów Front End w organizacji, weryfikacja logów na wszystkich serwerach może nie być specjalnie efektywna. Alternatywnie można wykorzystać inną metodę weryfikacji agentów. Jedną z metod jest odpytanie serwera backend SQL, gdzie w bazie rgsconfig jest tabela z listą agentów, w której możemy sprawdzić status EV agenta, poniższą komendą:
SELECT *
  FROM [rgsconfig].[dbo].[Agents]
  Where EnterpriseVoiceEnabled = 0
Możemy również użyć skryptu, który będzie sprawdzał właściwości poszczególnych agentów, poprzez sprawdzenie w pętli członków grup agentów (cmdlet Get-CsRgsAgentGroup). Ja napisałem sobie do tego funkcję:
function checkRGSpool {
    param (
        [string]$poolname
    $agentgroups = Get-CsRgsAgentGroup | Where-Object OwnerPool -eq $poolname
    ForEach ($agentgr in $agentgroups) {
        $groupname = $agentgr.Name
        write-host "Processing $groupname"
        if ($agentgr.AgentsByUri.count -gt 0) {
            $agents = $agentgr.AgentsByUri
            foreach ($agent in $agents) {
                $agent = $Agent.tostring()
                # write-host "Agent $agent"
                Try {
                    $currentagent = get-csuser $agent -ErrorAction Stop
                }
                Catch [Exception] {
                    write-host "Ghost agent found: $agent" -ForegroundColor Yellow
                }
                $agentlist += $agent
            }
        }
        else {
            write-host "$groupname has no Agents" -ForegroundColor Yellow
        }
    }
}

Możemy oczywiście funkcję rozbudować również o weryfikację statusu EV, ale to w kolejnej iteracji.

02 grudnia 2018

Przykłady dostosowywania TeamSites

Tydzień temu miałem przyjemność prowadzić prezentację na konferencji Sharecon 2018, dotyczącą automatyzacji zadań związanych z tworzeniem TeamSite'ów. Ostatnio trochę głębiej badałem ten temat w związku z projektami wdrażania Microsoft Teams (a przecież TeamSite na Sharepoincie Online jest tworzony dla każdego zespołu Teams). Prezentację uzupełniłem o przykłady wykorzystania powershella i stwierdziłem, że warto o tym parę słów napisać.
Pierwszy przykład, wykorzystujący Powershella związany był z zagadnieniem Sharepoint Site Theming. Możemy w prosty sposób utworzyć i zastosować własny temat kolorystyczny (skrypt yellowtheme.ps1), który  następnie możemy użyć do utworzenia sitescriptu, wykorzystanego następnie do zmiany domyślnego szablonu strony TeamSite.
#
# yellowtheme.ps1
#

Connect-PnPOnline -Url https://pepugnet-admin.sharepoint.com
$themepalette = @{
    "themePrimary" = "#ffdd00";
    "themeLighterAlt" = "#fffded";
    "themeLighter" = "#fff9d1";
    "themeLight" = "#fff090";
    "themeTertiary" = "#ffe53f";
    "themeSecondary" = "#ffde0b";
    "themeDarkAlt" = "#e6c700";
    "themeDark" = "#a38d00";
    "themeDarker" = "#8c7a00";
    "neutralLighterAlt" = "#f8f8f8";
    "neutralLighter" = "#f4f4f4";
    "neutralLight" = "#eaeaea";
    "neutralQuaternaryAlt" = "#dadada";
    "neutralQuaternary" = "#d0d0d0";
    "neutralTertiaryAlt" = "#c8c8c8";
    "neutralTertiary" = "#595959";
    "neutralSecondary" = "#373737";
    "neutralPrimaryAlt" = "#2f2f2f";
    "neutralPrimary" = "#000000";
    "neutralDark" = "#151515";
    "black" = "#0b0b0b";
    "white" = "#ffffff";
    "primaryBackground" = "#ffffff";
    "primaryText" = "#000000";
    "bodyBackground" = "#ffffff";
    "bodyText" = "#000000";
    "disabledBackground" = "#f4f4f4";
    "disabledText" = "#c8c8c8";
}

Add-PnPTenantTheme -Identity "yellowTheme" -Palette $themepalette -IsInverted $false

Powyższy skrypt działa bardzo prosto - łączymy się do naszego tenanta O365, a konkretnie do witryny administracyjnej SPO (w przykładzie używam swojego tenanta testowego). Następnie definiujemy paletę kolorystyczną naszego tematu - brzmi groźnie, jednak na stronie Theme Generator Tool jest dostępny online'owy edytor kolorów, który generuje nam od razu odpowiednią tablicę w Powershell, JSON lub kod JavaScript (od razu możemy przejść przez link do edytora online CodePen).
































Ostatni cmdlet w skrypcie definiuje nam nowy temat kolorystyczny na poziomie tenanta Office 365.
Warto przy okazji zauważyć, że oba cmdlety użyte w skrypcie znajdują się nie w domyślnym module administracyjnym Sharepoint Online ale w module SharePointPnPPowerShellOnline, czyli module Powershell udostępnionym w ramach Sharepoint Patterns and Practices (PnP). Moduł możemy sobie zainstalować ze standardowego repozytorium PSGallery (o konfiguracji komputera do administrowania Office 365 pisałem kilka miesięcy temu), uzyskując w ten sposób wiele dodatkowych możliwości zarządzania SPO.
Mając dodany na poziomie tenanta temat kolorystyczny, możemy go ręcznie przypisać do site'u (rysunek poniżej), albo użyć w konfiguracji domyślnego szablonu dla kolejnych witryn.
W tym celu musimy utworzyć plik JSON z definicją sitescriptu (poniżej), a następnie po połączeniu się do serwisu SPO, wykonać następujące polecenia:

$siteScript = (Get-Content 'c:\Scripts\TeamSite\spsitescript.json' -Raw | Add-SPOSiteScript -Title "ThemeDemo" -Description "Applies theme and nav link")  | Select -First 1 Id
Add-SPOSiteDesign -Title "Theme" -WebTemplate "64" -SiteScripts $siteScript.Id -Description "Applies standard company theme to site" -IsDefault


Pierwsza sekwencja tworzy site script na podstawie zawartości pliku JSON i zwraca identyfikator skryptu, a druga komenda tworzy zmodyfikowany szablon TeamSite (szablonu WebTemplate o numerze 64) i ustawia go jako domyślny dla naszego tenanta ($siteScript.Id to właśnie identyfikator naszego skryptu).
Jeżeli chcielibyśmy dostosować Site typu Communication, powinniśmy użyć WebTemplate o wartości 68. Jeżeli zostało wprowadzone ograniczenie na tworzenie zespołów Office 365, to żeby stworzyć Site typu zespołowego ale bez grupy Office 365, to WebTemplate powinien mieć wartość 1.
Zawartość JSON spssitescript.json wygląda następująco:
{
    "$schema": "schema.json",
        "actions": [
            {
                "verb": "addNavLink",
                "url": "https://techcommunity.microsoft.com",
                "displayName": "Aswers from Community",
                "isWebRelative": false
            },
            {
                "verb": "applyTheme",
                "themeName": "yellowTheme"
            }
        ],
        "binddata": {},
        "version": 1
}
Jak można się domyślić, patrząc na składnię pliku, definiowane są dwie akcje, które będą dodatkowo wykonywane podczas tworzenia nowej witryny typu TeamSite - dodawana jest pozycja do menu nawigacyjnego (link do portalu Techcommunity) oraz ustawiany jest temat kolorystyczny (zdefiniowany wcześniej na poziomie tenanta) widać to wyraźnie, gdy uruchomimy kreator tworzenia nowej witryny zespołu z poziomu portalu Sharepoint Online (rysunek poniżej).



















Więcej informacji na temat możliwych akcji przekazywanych przez JSON i poprawnej składni można znaleźć w dokumentacji Sharepoint. Inne przykłady zastosowania sitescriptów i dostosowywania wyglądu site'ów sharepoint Online można znaleźć na blogu Laury Kokkarinen. Jeżeli ktoś woli prezentację wideo, to warto obejrzeć również ten filmik.

08 listopada 2018

Zarządzanie chmurą z Powershell - ładowanie modułów

We wcześniejszym wpisie przedstawiłem kroki, które dobrze jest wykonać na standardowym komputerze Windows 10, przy pomocy którego chcemy administrować środowiskiem Office 365 i Azure. Piszę "i", a nie "lub", ponieważ środowiska te coraz głębiej się przenikają i o ile 2-3 lata temu można było zarządzać Office 365 bez odwoływania się do Azure, to teraz robi się to coraz trudniejsze.
Ale przejdźmy do konkretów - poszczególne obszary funkcjonalne mogą być zarządzane z poziomu Powershella, ale ponieważ są rozwijane przez różne grupy produktowe, więc jak można się domyślać, mamy do tego oddzielne moduły. Poniżej lista modułów, które dobrze jest zainstalować na swojej stacji administracyjnej.












Oprócz zaktualizowanej wersji modułu PowerShellGet widać tutaj moduły do zarządzania kontami chmurowymi i domenami chmurowymi, kontami AzureAD, również z użyciem Microsoft Graph (AzureADPreview) oraz kilka modułów dodatkowych jak np. Exch-Rest, opracowany przez Glena Scalesa, na potrzeby wykonywania akcji na Exchange Online z użyciem Rest API. Innym ciekawym modułem jest SharepointPnPPowerShellOnline, który pozwala na dodatkowe operacje na środowisku Sharepoint Online. Na powyższej liście nie widać modułów do Sharepointa online i Skype for Business Online.  Niestety trzeba je instalować i aktualizować w sposób tradycyjny. 

Update
Od niedawna dostepny jest nowy moduł do zarządzania Exchange Online - ExchangeOnlineManagement, który dużo prościej możemy zainstalować bezpośrednio z PowerShellGallery. Najnowsza wersja modułu jest dostępna również poprzez Powershell Core 7.x nie tylko na platformie Windows. Microsoft wycofał również moduł do zarządzania Skype for Business Online, niezbędne funkcjonalności dostępne są teraz w module Microsoft Teams, począwszy od wersji 2.0. Możemy również zainstalować z Powershell Gallery moduł do zarządzania Sharepoint.

W zależności od potrzeb, do wykonywania zadań administracyjnych potrzebujemy często załadować kilka modułów po kolei, do czego najwygodniej użyć skryptu. Kilka takich skryptów można znaleźć w galerii Technet lub na blogach innych specjalistów. Ostatnio również pojawił się artykuł na stronie z dokumentacją korzystania z powershella w Office 365 Procedura tworzenia takiego skryptu jest opisana również w dokumentacji Office 365. Ja najczęściej korzystam z takiego skryptu. Z lenistwa w skrypcie zapisuję odpowiednie konto administracyjne i odkomentowuję odpowiednie linie dotyczące aktualnie używanych modułów:

#

# get global admin credential

#

 

$credential = Get-Credential admin@pepug365.onmicrosoft.com

[string]$tenant = 'pepug365'

#

# connect to Azure AD

#

Import-Module MsOnline

Connect-MsolService -credential $credential

#

# connect to Sharepoint Online

#

Import-Module Microsoft.Online.Sharepoint.PowerShell

Connect-SPOService -url https://$tenant-admin.sharepoint.com -Credential $credential

#

# connect to Exchange Online

#

Connect-ExchangeOnline -UserPrincipalName admin@pepug365.onmicrosoft.com

#

# connect to to Microsoft Teams

#

Import-Module -Name MicrosoftTeams

Connect-MicrosoftTeams -Credential $credential

23 maja 2018

Zarządzanie chmurą z Powershell - przygotowanie

UPDATED: dodatkowe obrazki z obejściem problemu z repozytorium

Niedawno przygotowywałem krótką prezentację o zarządzaniu Office 365 z poziomu Powerhell. Na moim komputerze jest to proste - odpowiednie moduły instalowałem przez kolejne miesiące, jednak na świeżych komputerach z Windows 10 zauważyłem wiele drobnych problemów.
Dlatego też uznałem, że warto jest zrobić krótkie podsumowanie.
Większość modułów, która jest używana do zarządzania środowiskiem Office 365 lub Azure dostępna jest i aktualizowana w PowerShell Gallery (www.powershellgallery.com). Kiedy jednak chcemy je zainstalować w systemie, pojawiają się błędy. W czym leży problem?
Do instalacji modułów powershell z galerii używany jest moduł PowerShellGet, który w Windows 10 dostarczany jest domyślnie z systemem w ramach PowerShell 5. Niestety dostarczany jest on w wersji 1.0.0.1, jak widać na poniższym obrazku po wykonaniu komendy
get-module PowerShellGet -ListAvailable








Dodatkowo pomocniczy pakiet NuGet również nie jest najnowszy i próba instalacji modułu zwraca komunikat o potrzebie aktualizacji dostawcy. Co powinniśmy zatem zrobić? Wymusić aktualizację obu pakietów, jak pokazują kolejne obrazki. Aktualna wersja pakietu NuGet w momecie pisania artykułu to 2.8.5.208:





W niektórych wypadkach dobrze jest po aktualizacji NuGet zamknąć powłokę, bo nie zawsze odświeżą się zmienne środowiskowe i kolejna próba instalacji znowu stwierdzi, że wersja NuGet jest zbyt stara.
Oczywiście wszystkie instalacje wykonujemy w kontekście administratora.
Teraz czas na aktualizację PoweShellGet. Ponieważ był instalowany z systemem, nie możemy użyć cmdleta update-module, musimy wymusić instalację:


Sprawdzamy rezultat:








Jak widać, jest wersja oryginalna i wersja najnowsza, którą możemy już normalnie aktualizować i domyślnie używać.
Czasami jednak możemy natknąć się na taki problem, sygnalizujący brak dostępu do repozytorium:






O co chodzi? Sprawdzam dostępne dla maszyny repozytoria i faktycznie widać jego brak:



Po zarejestrowaniu galerii pojawia się ona na liście repozytoriów, jak pokazuje kolejny obrazek (co ciekawe, nie działa komenda standardowa, z podaniem nazwy i urla PSGallery, trzeba użyć komendy z opcją domyślną -  Register-PSRepository -Default.






Mając zaktualizowany moduł PoweShellGet możemy również użyć nowych cmdletów w nim zawartych (np. get-installedmodule). Jednak przy instalacji lub aktualizacji modułów otrzymamy komunikat:






Możemy się go pozbyć w prosty sposób, wykonując komendę jak na kolejnym obrazku:



Teraz już bez problemów możemy przystąpić do zarządzania środowiskiem chmurowym, instalując potrzebne moduły, takie jak MSOnline, AzureAD, MicrosoftTeams. Trochę więcej na ten temat w kolejnym poście z tego cyklu.

01 sierpnia 2017

Sprawdzanie konfiguracji serwerów Exchange

Ciekawe skrypty powershellowe przeważnie wrzucam na Twittera. Jednak weryfikacja i kontrola konfiguracji serwerów to temat na tyle istotny, że warto czasem do niego wrócić w nieco szerszym aspekcie. Kiedyś Microsoft udostępniał narzędzie ExBPA - Exchange Best Practices Analyzer, naajpierw dostępny osobno, później dodawany do binariów Exchange. Niestety, Od wersji 2013 w zasadzie narzędzie znikło. Pojawiło się co prawda w formie szczątkowej po wielu miesiącach przerwy, ale tak naprawdę miało za zadanie głównie weryfikację pod kątem integracji środowiska lokalnego z Office365.
Od czego jednak Powershell? Czego nie ma w pakiecie, można dopisać sobie w powershellu, a jeżeli nie potrafimy, lub nie mamy czasu, to możemy gotowego skryptu poszukać w internecie. Nieocenionym źródłem jest Technet Gallery, gdzie jest ponad 1000 skryptów dla Exchange i wiele więcej dla innych obszarów technologii Microsoft. Sam opublikowałem tam kilka skryptów, ale bardzo często korzystam z narzędzi stworzonych przez Steve'a Goodmana, Paula Cunninghama czy Ingo Gegenwartha. Inni specjaliści, jak np. Pat Richard publikują skrypty na swoim blogu, jednak ostatnio coraz więcej ciekawych narzędzi można znaleźć na githubie. Tam też wczoraj znalazłem bardzo pożyteczny skrypt Davida Paulsona o nazwie HealthChecker. Sprawdza on podstawowe parametry hosta, nie zawsze oczywiste (jak np. włączony hyperthreating, którego zespół produktowy nie zaleca ze względów wydajnościowych). Na platformach wirtualnych część opcji nie ma zastosowania, ale nawet wtedy możemy sprawdzić np. ustawienia pliku wymiany, planu zasilania czy zainstalowanie niestandardowych poprawek dotyczących wydajności, jak pokazuje poniższy rysunek. Zdecydowanie polecam.
healthchecker.ps1 results

11 października 2016

Naprawa statusu usług Exchange

Pół roku temu opublikowałem na blogu skrypt, który przywracał poprawny status wszystkich usług Exchange, wyłączonych przez niepoprawnie zakończoną aktualizację. Jednak nie byłem zadowolony z takiej postaci skryptu i nieco go poprawiłem. Zamiast wypisywać kolejne komendy zmiany statusu usług Exchange, nowa wersja skryptu pobiera listę usług oraz poprawny status usługi z pliku csv (dwie kolumny - SrvName i Mode) i następnie w pętli dla każdej z usług sprawdza, czy nie ma ona statusu "Disabled".

Ponieważ parametr filtrowania wyników oczekuje czystego stringu a nie zmiennej, więc dodatkowo tworzę zmienną, zawierającą definicję filtru dla konkretnego serwisu.
Jeżeli usługa ma tryb uruchomienia ustawiony na "Disabled", to skrypt zmienia ustawienia serwisu zgodnie z informacjami w drugiej kolumnie pliku csv. Taką wersję skryptu opublikowałem w galerii Technet. Skrypt należy uruchamiać w kontekście administratora (zmienia ustawienia usług systemowych), ale nie potrzebuje powłoki Exchange ponieważ działa tylko na poziomie WMI i serwisów.

27 lutego 2016

Dynamiczne grupy dystrybucyjne - filtrowanie użytkowników

Tworząc dynamiczne listy dystrybucyjne czy polisy list adresowych w panelu administracyjnym serwera Exchange możemy wybrać tylko kilka podstawowych atrybutów - "State or province", "Country", "Department" oraz jedną z 15 wartości Custom Attributes (rysunek poniżej).




















Co jednak w przypadku, gdy chcemy stworzyć filtr na podstawie np. nazwy miasta? Czy trzeba tą wartość skopiować do Custom Attribute? Na szczęście nie jest to potrzebne.
Zespół produktowy uwzględnił jeszcze wiele innych atrybutów, jednak w żadnej wersji systemu nie umieścił ich w kreatorze. Żeby było ciekawiej, nazwy atrybutów Exchange nie zawsze są takie same w Exchange, co w Active Directory, a niektóre atrybuty nie mają nawet swoich odpowiedników w AD (!). Żeby nie popełnić błędu dobrze jest sprawdzić listę, która jest dostępna np. w artykule
Na liście musimy zatem odszukać odpowiedni nazwę odpowiedniego atrybutu. Jeżeli chcemy filtrować po nazwie miasta, np. Warszawa, to musimy utworzyć grupę, wykonując komendę:
New-DynamicDistributionGroup -Name WawaUsers -RecipientFilter {(City -eq 'Warszawa')}
Co ciekawe, jak podejrzymy właściwości tak zdefiniowanej grupy, to zobaczymy komunikat, że filtr został utworzony w Powershellu i w ten sam sposób może być zmieniony (rysunek poniżej).













Jeżeli sprawdzimy właściwości z poziomu shella, to zobaczymy, że system automatycznie dodał dodatkowe warunki, doprecyzowujące zakres filtrowania:







Jak widać, możemy w wyrażeniach, będących elementami filtru stosować wilcard i różne wyrażenia logiczne.

26 lutego 2016

Uprawnienia do wysyłania w imieniu skrzynki współdzielonej

Temat wydaje się banalny - w systemie Exchange we właściwościach skrzynki użytkownika możemy przypisać uprawnienie zarówno "Send As" jak i "Send on behalf".
Jednak gdy wejdziemy w Exchange 2013 lub 2016 we właściwości skrzynki współdzielonej (shared), to zauważymy, że w Exchange Admin Center okienka, w którym moglibyśmy przypisać uprawnienie "Wyślij w imieniu" po prostu nie ma. Błąd, czy inne właściwości? Niemożliwe, bo przecież możemy zmienić typ skrzynki z osobowej na użytkownika jedną prostą komendą set-mailbox.
Można się domyślić, że jak czegoś nie ma w konsoli webowej, to jest to nadal dostępne z poziomu Management Shella. Tak jest i w tym przypadku.
Jeżeli wykonamy komendę:
Get-mailbox | fl GrantSendOnBehalfTo
lub bardziej ogólnie
Get-mailbox -RecipientTypeDetails shared | fl name,GrantSendOnBehalfTo






To zobaczymy, że taki atrybut jest obecny. Wystarczy teraz przypisać uprawnienie:
Get-mailbox | set-mailbox -GrantSendOnBehalfTo 
Prawidłowo wykonana komenda nie zwróci nam żadnych informacji, ale po ponownym sprawdzeniu uprawnień, zobaczymy nową wartość w tablicy kont uprawnionych do wysyłania w imieniu danej skrzynki:

16 listopada 2015

Automatyzacja konfiguracji wirtualnych katalogów Exchange

Zaczął się sezon na migracje, także do Exchange 2016. Jednym z elementów konfiguracji jest odpowiednie przygotowanie wirtualnych katalogów dla roli CAS. Exchange od dawien dawna dla  każdej z usług webowych udostępnia nazwę zewnętrzną (exernal URL) i wewnętrzną (internal URL). Od Exchange 2013 ten dualizm dotyczy również usługi Outlook Anywhere – wcześniej można było zdefiniować tylko publiczną nazwę hosta dla tej usługi. Żeby było ciekawiej, nie wszystkie nazwy można skonfigurować przez Exchange Admin Center, co utrudnia proces. Dla jednego serwera musimy zdefiniować więc następujące URL-e:

  • dwa dla usługi ActiveSync,
  • dwa dla OWA,
  • dwa dla ECP,
  • dwa dla OAB,
  • dwa dla EWS,
  • dwa dla Outlook Anywhere,
  • dwa dla Poweshell,
  • dwa dla MAPI (jeżeli włączamy ten typ dostępu),
  • jeden dla Autodiscover (jako atrybut serwera CAS)

Daje nam to 17 URL-i na jeden serwer (!), czyli całkiem sporo. A jeżeli w organizacji mamy kilka takich serwerów do skonfigurowania daje nam to odpowiednio więcej wpisów. Jakiś rok temu, żeby zaoszczędzić sobie pracy przygotowałem (a w zasadzie uaktualniłem) skrypt, który automatyzuje ten proces, jak widać na poniższym rysunku. W ostatni weekend znalazłem chwilę, żeby to trochę poprawić i dopasować do Exchange 2016. Zapraszam do korzystania i przekazywania sugestii na temat możliwych ulepszeń.

działanie skryptu set-allvdirs.ps1

22 października 2015

Wyłączanie chwilowe Direct Access na kliencie

Dawno nie pisałem, ale nadmiar pracy i testy nowych technologii, które miały status NDA trochę mi to utrudniały. Ale żeby nie zapomnieć chciałem dodać jedną informację o używaniu Direct Access. Jest to świetna technologia, człowiek cały czas podłączony jest do lokalnych zasobów firmowych, może używać krótkich nazw serwisów intranetowych niezależnie od tego, gdzie jest podpięty. Jednak czasem bywa to uciążliwe, zwłaszcza gdy chcemy sprawdzić poprawność publikowanych usług od strony Internetu. Do wyłączenia Direct Accessa niezbędne jest zatrzymanie dwóch usług systemowych – asystenta usług sieciowych i IP Helpera, co w normalnych warunkach wymaga odpalenia konsoli services.msc, znalezienia odpowiednich usług i ich zatrzymanie. Oczywiście odwrócenie konfiguracji wymaga włączenia tych usług lub restart komputera. Dużo szybciej jest przygotować sobie skrypt powershell, który możemy “prawokliknąć” i wybrać opcję “Run with powershell”. Cały problem polega na tym, że zatrzymanie usług wymaga odpalenia skryptu z wyższymi uprawnieniami (nieszczęsny UAC). Pomyślałem sobie, że najprościej włączyć eskalację uprawnień wewnątrz skryptu, co też uczyniłem, wykorzystując konstrukcję opisaną na blogu Bila Armstronga - http://blogs.msdn.com/b/virtual_pc_guy/archive/2010/09/23/a-self-elevating-powershell-script.aspx:

#
# script to stop Direct Access on user computer
# if user has local administrator permission
#

# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
 
# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
 
# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
    {
    # We are running "as Administrator" - so change the title and background color to indicate this
    $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
    $Host.UI.RawUI.BackgroundColor = "DarkBlue"
    clear-host
    }
else
    {
    # We are not running "as Administrator" - so relaunch as administrator
   
    # Create a new process object that starts PowerShell
    $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
   
    # Specify the current script path and name as a parameter
    $newProcess.Arguments = $myInvocation.MyCommand.Definition;
   
    # Indicate that the process should be elevated
    $newProcess.Verb = "runas";
   
    # Start the new process
    [System.Diagnostics.Process]::Start($newProcess);
   
    # Exit from the current, unelevated, process
    exit
    }
 
 
stop-service NCASvc
stop-service iphlpsvc

Na podobnej zasadzie można oczywiście realizować inne operacje cykliczne operacje, np. zmiany adresu IP.