Veel kord kasutajaprofiilidest

Sai kunagi kirjutatud, kuidas Powershelli abiga kasutajaprofiile üles leida ja kustutada.  Vahepeal on aeg edasi läinud ja uued Powershelli versioonid oskavad samu asju natuke paremini teha.  Sellega seoses sai kirjutatud moodul, mis võimaldab kasutajaprofiilide haldust automatiseerida.  Mooduli leiab Technet Script Gallery’st ja Powershell 5.0 omanikud võivad selle alla tõmmata Powershell Gallery‘st.  Viimaste jaoks on see käsurealt ülilihtsalt teostatav:

#otsi
Find-Module -Name UserProfile

#paigalda
Install-Module -Name UserProfile

Mooduli kasutamine käib järgnevalt:

#Find all user profiles except special system profiles.
Get-UserProfile -Special $false

#Delete all roaming profiles that are not used for 3 months.
$myDate = (Get-Date).AddDays(-90)
Get-UserProfile -Before $myDate -Roaming $true -Loaded $false |
  Remove-UserProfile

#Find user profile of specific user.
Get-AdUser John | Get-UserProfile

#Find all roaming profiles from specific computers.
$session = new-cimsession -ComputerName srv1,srv2 -credential domain\user
Get-UserProfile -CimSession $session -Roaming $true

#Migrate local user account profile into domain user account profile.
$oldAccount = Get-CimInstance Win32_UserAccount -filter "caption='PC\\user'"
$newAccount = Get-AdUser Mati
$oldAccount | Get-UserProfile | Set-ProfileOwner -SID $newAccount.SID

#discover user profile owner by folder name
Get-Item c:\users\kasutaja |
  Select-Object -ExpandProperty FullName |
  Get-UserProfile |
  Get-ProfileOwner

Ülalmainitud moodul töötab ilusti ka Windows 7 ja Server 2008 R2 peal ning võib-olla et isegi Vista/Server 2008 peal, kui sinna Powershell 3.0 paigaldada.  Pole hetkel Vista masinat kuskilt võtta, seega ei saa proovida.

Loodetavasti on antud moodul mugavam kasutada, kui kunagi pakutud skriptinäide.

SSH tugi Powershellis

Powershelli tootetiim andis teada, et nad alustasid SSH protokolli toe planeerimist Powershellile.  Seda siis muuseas ka sedapidi, et eemalt masinast saab teha SSH ühenduse ja sihtpunktis kasutada Powershelli.

Teistpidi lahendusi (Powershell teeb SSH sessiooni teise masinasse) on juba mõnejagu olemas.  Näiteks võiks mainida moodulit Posh-SSH.  Kommertstoodetest võiks mainida PowershellServerit, millest on tasuta personaalne versioon olemas.  Samuti võib võtta suvalise Windowsi peal töötava SSH serveri ja kasutada selle sees käsurea interpretaatoriks Powershelli.

Nimetatud funktsionaalsust on korduvalt Powershelli tagasiside veebis küsitud.

Seisuga Oktoober 2015 on valmis saadud OpenSSH for Windows, mis on esialgu veel arendamisel, ent tulemus lubatakse valmis saada järgmise aasta esimeses pooles.

Powershell 5 Preview April 2015

Järjekordne versioon Windows Management Framework 5.0 eelvaatest.  On möödunud aasta esimesest eelvaatest ja seekord saab seda paigaldada ka Windows 7/Server 2008 R2 ja Server 2012 peale.

Uusi asju on juurde tulnud päris palju.  Muudatusi on nii väikeseid kui suuri.  Peamised suured asjad on ikka Desired State Configuration ja moodul PowershellGet.  Aga on ka pisikesi asju, nagu näiteks Get-Clipboard, Set-Clipboard ja New-TemporaryFile.

Nagu eelvaatega ikka, kui leiad midagi, mida tahad muuta, siis kirjuta aadressil https://connect.microsoft.com/PowerShell/Feedback , või siis vähemalt hääleta juba kirjutatud asjade seas neid, mis ka Sinu arust vajalikud on.

Veel kord korduseksamitest

Eelmisel aastal oli juttu Microsofti MCSE/MCSD tiitlite korduseksamitest.  Nüüd on Microsoft välja mõelnud alternatiivi korduseksamile.  Nimelt saab minna Microsoft Virtual Academy (MVA) vebisaiti ja seal tuleb lihtsalt läbida ettenähtud kursused (sealhulgas vastata õigesti kõigile küsimustele kursuse sees).  Ja kui see on tehtud, siis tuleb sellest Microsoftile teada anda.  Ning tiitel ongi värskendatud.

Esialgu on kursuste nimekirjad olemas SQL-i MCSE-dele.  Ülejäänud tiitlitele pidid kursuste komplektid lisanduma järgmise aasta jooksul. Nimekirjad ja vastused korduma kippuvatele küsimustele leiab Microsofti saidist. Positiivne on see, et MVA kursused on tasuta.  Seega ei pea enam eksami peale raha kulutama.  Selle asemel kulutad aega (umbes 10 kursuse läbimiseks).  Või siis oled ettenägelik ja lähed juba kohe MVA veebisaiti kursuseid läbima …

Powershell ja sündmuste logid

Aeg-ajalt on vaja otsida sündmuste logidest teatud kindlaid sündmusi.  Ja vahel oleks hea ka ise sündmusi logida.

Vaatame kõigepealt, kuidas sündmusi leida.  Selleks on Powershellis kaks käsku: Get-EventLog ja Get-WinEvent.  Esimest neist tuleks kasutada ainult juhul, kui on vaja otsida sündmusi Windows Server 2003 logidest.  Ja Server 2003 tugi lõpeb sel aastal ära.

Kõigi uuemate OS-ide puhul tuleks kasutada teist käsku.  See oskab otsida sündmusi ka Event Tracing for Windows logidest.  Ja neid logisid on tänapäeval palju.  Alustamegi siis sellest, et otsime meid huvitava logi üles:

Get-WinEvent -ListLog *
Get-WinEvent -ListLog Application

Nüüd teades logi nime, saame sealt otsida sündmusi.  Piirame selle otsimise mingi arvuga, et mitte liiga kaua oodata:

Get-WinEvent -LogName Application -MaxEvents 10
Get-WinEvent -LogName "Windows Powershell" -MaxEvents 10

# vanemad sündmused enne
Get-WinEvent -LogName Application -MaxEvents 10 -Oldest

Tavaliselt ei huvita meid kõik logisse kirjutatud sündmused, vaid ikka spetsiifilised.  Lisaks võivad huvipakkuvad sündmused olla kirjutatud ka mitmesse erinevasse logisse.  Seetõttu saab sündmusi otsida ka mitte logide, vaid hoopis sündmuse allika järgi.  Kõigepealt leiame olemasolevate sündmuste küljest allikad:

(Get-WinEvent -ListLog Application).ProviderNames

Get-WinEvent -ListProvider *
Get-WinEvent -ListProvider *PowerShell
Get-WinEvent -ListProvider Outlook

Nüüd teades allikat, on lihtne saada kätte sündmused:

Get-WinEvent -ProviderName Outlook -MaxEvents 10
Get-WinEvent -ProviderName Microsoft-Windows-PowerShell -MaxEvents 10

Teades täpsemalt mida otsime, saame ka sündmusi täpsemalt filtreerida.  Näiteks võime me vaadata ainult viimase 24 tunni jooksul toimunud sündmusi:

$eile = (Get-Date).AddDays(-1)
Get-WinEvent -FilterHashtable @{
  LogName = "Application"
  StartTime = $eile
}

Või siis otsime me kindlat sündmust, mille puhul on teada ka sündmuse number (EventID):

Get-WinEvent -MaxEvents 10 -FilterHashtable @{
  ProviderName = "Outlook"
  ID = 32
}

Get-WinEvent -FilterHashtable @{
  Logname="Application"
  ProviderName="Application Error"
  Data="iexplore.exe"
}

Kui me oleme eelnevalt rakenduses Event Viewer loonud sündmuste filtri, siis selle saab ette anda ka Powershellile.  Vaja see vaid salvestada XML failiks ja sealt võtta välja element QueryList.  Selle saab ka vaate filtrit muutes vahelehelt XML.

Get-WinEvent -MaxEvents 10 -FilterXml @"
<QueryList>
  <Query Id="0" Path="Application">
    <Select Path="Application">*[System[Provider[@Name='Application Error'] and (Level=2) and (EventID=1000)]]</Select>
  </Query>
</QueryList>
"@

Get-WinEvent -FilterXml ([xml](Get-Content .\filter.xml)) -MaxEvents 10

XML-dokumendiga tasub jännata ainult keerulisemate päringute puhul, mida varem näidatud viisidel ei saa kokku panna (näiteks, kui on vaja leida mitmele erinevale EventID-le vastavaid sündmusi vms.).

Logidesse kirjutamisega on asi natuke keerulisem.  Nimelt tuleks oma skripti jaoks luua uus logi või siis vähemalt uus sündmuste allikas.  Muidu on pärast raske oma skripti sündmusi üles leida.  Ja nii uute logide kui ka uute allikate loomiseks on vaja süsteemiülema õigusi:

$myProvider = "minuskript"

#Requires -RunAsAdministrator
New-EventLog -LogName Application -Source $myProvider
New-EventLog -Source TestApp -LogName TestLog

try {
  Get-WinEvent -ListProvider $myProvider | Out-Null
} catch {
  Start-Process -Verb runas powershell.exe -ArgumentList "New-EventLog -LogName Application -Source $myProvider"
}

Ülaltoodud tegevus tuleb sooritada ühekordselt.  Pärast seda on uus logi/allikas masinas defineeritud ja skript saab rahulikult kirjutada sündmusi:

$params = @{
  LogName = "Application"
  Source = $myProvider
  EventId = 1
  Message = "Minu kohandatud sündmus"
}
Write-EventLog @params

Get-WinEvent -ProviderName $myProvider

Powershell 5.0 eelvaade

Veebruaris tuli välja järjekordne versioon Windows Management Framework 5.0-st.  Võrreldes varasemate versioonidega on nüüd näiteks tööle hakanud kõik erinevad linkide versioonid:

New-Item -ItemType File -Path asi.txt
New-Item -ItemType Directory -Path kaust

#Requires -Version 5
New-Item -ItemType HardLink -Name sama.txt -Value .\asi.txt
New-Item -ItemType Junction -Path .\kaustalink -Value .\kaust

#Requires -RunAsAdministrator
New-Item -ItemType SymbolicLink -Path .\uus.txt -Value .\asi.txt
New-Item -ItemType SymbolicLink -Path .\uuskaust -Value .\kaust

Veel üks uus ja põnev omadus on oma skripti lähtekoodi analüüs, kasutades etteantud või ise lisatud reegleid.

Sama versioon (või versiooninumbri järgi isegi värskem versioon) on ka Windows 10 sees.

E-maili aadresside eemaldamine Exchange serveris

Meiliaadresside lisamine on tavaliselt lihtne. Kui seda on vaja paljudele, siis muudame meiliaadreside poliitikat; kui seda on vaja üksikutele, siis lihtsalt lisame.

Eemaldamisega on lugu natuke keerulisem.  Kõigepealt tuleb üles leida adressaadid, kellel on sobiv aadress.  Üldiselt sobib selleks käsk Get-Recipient, aga teeme seda lihtsuse huvides ainult postkastidega:

$EmailFilter = "*@minu.ee"
$kastid = Get-Mailbox -ResultSize Unlimited |
  Where-Object EmailAddresses –Like $emailFilter

Kui adressaadid leitud, siis tuleb üles leida ka konkreetne eemaldamist vajav aadress.  Seda peamiselt seetõttu, et olemasolevate aadresside loendist ei saa eemaldada aadressi mustri järgi, vaid tuleb esitada täisaadress:

$kastid | Foreach-Object {
  foreach ($address in $_.emailaddresses) {
    if ($address -like $EmailFilter) {
      New-Object PSObject -Property @{Name=$_.name; Alias=$_.alias ; SmtpAddress=$address}
    }
  }
}

Tulemuseks kuvatakse hetkel meile kõik leitud meiliaadressid koos postkasti nimega, mille küljes see aadress on.  Nii et nüüd jääb üle asendada kuvamine kustutamisega.  Siin saab ära kasutada Exchange serveri üldist lähenemist: kui atribuudil võib olla mitu väärtust, siis saame olemasolevate väärtuste hulgas teha muutusi (lisada, eemaldada, asendada)

      Set-Mailbox -Identity $_.id -EmailAddresses @{remove=$address}

Ülaltoodud näide töötab Exchange 2010..2016 peal.  Exchange 2007-l ei olnud veel seda mainitud üldist lähenemist loodud, seega peab seal tegema natuke teistmoodi:

      $NewAddresses = $_.emailaddresses - $address
      Set-Mailbox -Identity $_.id -EmailAddresses $NewAddresses

Kui nüüd peaks vajadus tekkima eemaldada aadresse gruppide, kontaktide või muude adressaatide küljest, siis tuleb lihtsalt asendada adressaatide leidmise ja muutmise käsud.  Muu loogika peaks samaks jääma.