Category Archives: Powershell

Exchange 2010: 554 5.1.0 Sender denied, PerRecipientBlockedSender

Danas sam imao vrlo zanimljivu situaciju pošto su mi kolege prijavile da ne mogu da šalju mejlove samo jednoj osobi u našoj korporaciji, dok im poruke prolaze ka svim ostalim primaocima. Inače domen sa koga šalju nije na našem Exchange serveru već se koristi drugi mejl server (tip nije bitan u ovom slučaju). Dakle recimo da su u pitanju adrese predrag@nesto.rs kao primaoc i rajco@domen.com kao pošiljaoc.

U ovom slučaju kada Rajco pošalje poruku Predragu dobije sledeću grešku:

User and password not set, continuing without authentication.
<predrag@nesto.rs> 93.87.xxx.xxx failed after I sent the message.
Remote host said: 554 5.1.0 Sender denied

Pošto mi ne koristimo u ovom slučaju Edge server, na HUB serveru pod opcijom Anti-Spam, sam proverio da li je adresa rajco@domen.com slučajno blokirana, ali to nije bio slučaj:

554 5.1.0 Sender denied 01

Dodavanje kompletnog domena ili adrese u IP Allow List ne pomaže u ovom slučaju, pa sam morao da pogledam detaljnije logove u potrazi za ovom greškom. To radimo sa sledećom komandom u EMS:

Get-Agentlog | where {$_.SmtpResponse -eq "554 5.1.0 Sender denied"}

554 5.1.0 Sender denied 02

E odavde je već lakše, vidimo u crvenom delu da je korisnik blokirao pošiljaoca u svom outlook-u. To se može desiti i slučajno ako je korisnik prevukao mejl u junk pa odabrao da ubuduće blokira pošiljaoca. Da bi bili sigurni da je konkretna mejl adresa blokirana kod samog korisnika možemo iskoristiti komandu:

Get-MailboxJunkEmailConfiguration -Identity predrag@nesto.rs

Koji nam vraća listu TrustedSendersAndDomains i BlockedSendersAndDomains:

554 5.1.0 Sender denied 03

Određena polja su zatamljena jer su slike preuzimane sa servera koji je u produkciji, ali ne bi trebalo da utiče na razumevanje teksta.

Pretraga i filtriranje računara u Active Directory pomoću Powershell-a

Često se dešava da nam Active Directory nije potpuno ažuriran u smislu da imamo nekih računara koji se više ne koriste, a nalaze se u različitim organizacionim jedinicama pa bi ih bilo vrlo teško locirati bez PowerShell-a. Jedan od načina je da pronađemo računare na koje je poslednje logovanje bilo pre više od 100 dana i prebacimo ih u jednu organizacionu jedinicu gde ih kasnije možemo brisati.

Prvo ćemo postaviti željeni datum u promenljivu d sa komandom:

$d = [DateTime]::Today.AddDays(-100)

Zatim ćemo iskoristiti komandu koja pretražuje i izlistava računare u AD, Get-ADComputer, a zatim sa filter parametrom izlistati sve računare koji su u statusu enable i kojima je zadnji datum logovanja manji ili jednak od datuma koji smo stavili u promenljivu $d.

Get-ADComputer -filter {(enabled -eq "true") -and 
(lastlogondate -le $d)} -properties Name,LastLogonDate

Nakon toga možemo sve računare prebaciti u novu OU:

Move-ADObject -Targetpath 'ou=Disabled Computers,dc=rajco,dc=me'

Ukoliko hoćemo više detalja o svojstvima računara koje ćemo dobiti u rezultatu možemo koristiti komandu:

Get-ADComputer -filter {(enabled -eq "true") -and (lastlogondate -le $d)} -Properties * |
ft name, lastlogondate, operatingsystem
Get-ADComputer -filter {(enabled -eq "true") -and (lastlogondate -le $d)}`
-Properties * | select Name, LastLogonDate, OperatingSystem | Out-GridView

Evo kako izgledaju rezultati poslednje dve komande respektivno:

PS_AD01

PS_AD02

Ukoliko pretragu želimo da izvršimo prema imenu računara komanda bi izgledala:

Get-ADComputer -Filter "Name -like '*AICABO*'" | ForEach-Object {$_.Name}

Sada se možemo poigrati i pronaći sve željene računare i proveriti veličinu particija i slobodnog prostora:

 $Computers = Get-ADComputer -Filter "Name -Like '*AACABO*'" |
 ForEach-Object {$_.Name}
Get-WMIObject Win32_LogicalDisk -filter “DriveType=3" -computer $computers | `
Select SystemName,DeviceID,VolumeName,@{Name=”size(GB)”;Expression=`
{“{0:N1}” -f($_.size/1gb)}},@{Name=”freespace(GB)”;Expression={“{0:N1}” `
-f($_.freespace/1gb)}} | Out-GridView

PS_AD04

Mogućnosti su velike, pa možete sami da nastavite sa isprobavanjem komandi po vašoj želji i potrebama.

RSAT Tools i Powershell pretraga zaključanih naloga

Iskoristiću ovaj post da objasnim instaliranje i korišćenje RSAT alata, a zatim da dam primer korišćenja Powershell-a preko RSAT-a. RSAT (Remote Server Administration Tools) nam dozvoljava upravljanje rolama i karakteristikama (Roles and Features) koje su instalirane na udaljenom serveru sa operativnim sistemom Windows Server 2008 i 2008R2 (važi i za pojedine role i karakteristike na verziji servera 2008 i 2003). Na primeru koji ću pokazati vidimo koliko je RSAT koristan, ne samo u olakšavanju upravljanja, već i donošenjem novih i poboljšanih komandi.

RSAT je dostupan za obe arhitekture procesora (x86 i x64) a obradićemo verziju za Windows 7 SP1 (mora biti u ediciji Enterprise, Professional ili Ultimate). Bitna stavka je da alat dolazi u vidu ažuriranja i mora se potpuno ukloniti svaka prethodna verzija pre instalacije nove, podrazumeva se da se ne može instalirati na ciljanom serveru. Takođe su nam potrebna administratorska prava na računaru na kom istaliramo alat. Kada završimo instalaciju ostaje nam da u Control Panelu pod opcijom Program and Features dodamo karakteristike i role sa kojim želimo da upravljamo.

RSAT-01

Sada možemo da počnemo sa upravljanjem željenih rola na ciljanom serveru/serverima. Ukoliko ste na klijentskom računaru već logovani kao administrator sa potrebnim pravima na udaljenom serveru onda je dovoljno samo da pokrenete neki od alata. Pošto nije dobra praksa biti logovan na klijentski računar i raditi stalno sa administratorskim pravima onda je potrebno alat pokrenuti kao drugi korisnik i ukucati administratorske kredencijale. Takođe postoji opcija prilikom korišćenja Powershell-a da prilikom izvršavanja same komande obezbedimo kredencijale koji su dovoljni za tu akciju i time izbegnemo rad sa pravima većim od potrebnih.

RSAT-02

Na ovom primeru vidimo da su instalirani svi dostupni alati jer računar nije u produkciji, već u testnom okruženju. Vi ćete naravno izabrati alate za role koje imate instalirane. U svakom trenutku možete dodati i neki koji vam kasnije zatreba. Kao što sam rekao na sledećem primeru ćemo videti kolika je korist od RSAT-a.

Ukoliko dobijete zadatak da proverite sve zaključane naloge u vašem domenu a pri tome imate stotine ili hiljade naloga taj posao ručno bi bio nemoguć, a ako je domain controler na verziji nižoj od Windows Servera 2008 R2 trebaće vam neki PS skript ili ne daj bože VB :). Uz pomoć RSAT alata to možemo uradti sa jednom komandom na sledeći način:

RSAT-03

Search-ADAccount -LockedOut

U prvom redu izlistavamo sve zaključane naloge na domenu.

Search-ADAccount -LockedOut | Unlock-ADAccount

Drugim redom prosleđujemo (pipe) komandu za otključavanje svih naloga. Ukoliko nemamo dovoljna prava ovde možemo dobiti grešku pa je potrebno ponoviti akciju sa odgovarajućim dozvolama. Na kraju ponavljamo prvu komandu da bi se uverili da smo otključali sve naloge. Sve ovo smo radili sa klijentskog računara i pokrenutim Active Directory Module for Powershell, da smo pokrenuli samo Powershell morali bi da importujemo odgovarajući modul sa komandom:

Import-Module ActiveDirectory

Velika verovatnoća je da ne želimo da otključamo sve naloge, već da izaberemo pojedinačno, tada koristimo

RSAT-04

Imamo parametar confirm pa će nam PS tražiti da potvrdimo svaki nalog pojedinačno. Takođe u nastavku vidimo da možemo koristiti select da bi izabrali polja u prikazu koja nas interesuju.

PS C:\Users\Administrator> Search-ADAccount -LockedOut | select Name

Kao što vidimo sada vrlo lako možemo vršiti upravljanje serverima sa lokalnog računara čak i uz korišćenja komandi koje nam ne bi bile dostupne na serveru. Još jedna velika prednost je ukoliko više administratora koristi RDP konekciju ka serverima, a znamo da je, ne računajući terminal servise, ili po novom RDP rolu, broj istovremenih RDP konekcija dve, tako da treći administrator neće moći da pristupi serveru bez da izloguje jednog od prve dvojice ili odlaskom do servera i logovanjem lokalno.

Uključivanje i podešavanje Windows PowerShell Remoting-a pomoću grupnih polisa

Sa PowerShell-om verzije 2.0 dodata je nova mogućnost udaljenog korišćenja PS-a, PowerShell remoting. Možemo ga uključiti sa jednostavom komandom:

Enable-PSRemoting

Bolja varijanta je da to uradimo preko grupnih polisa (Group Policy), podrazumeva se da je okruženje domensko a ne okruženje radne grupe. Ovo važi za Vistu, Windows 7, Windows Server 2008 i Windows Server 2008R2, za server 2003 i XP je najbolje “pustiti” script koji će uključiti PS remoting.

PS 2.0 i WinRM 2.0 dolaze sa Win 7 i Server 2008R2 dok ih je za starije operativne sisteme potrebno instalirati(najbolje preko WSUS-a).

Prvi korak je da otvorimo Group Policy na domen kontroleru napravimo polisu i odemo pristupimo podešavanju iste, Computer Configuration->Policies->Administrative templates->Windows Components

PSRemoting01 

PSRemoting02

Potrebno je da podesimo automatic listener koji “sluša” stalno da li ima zahteva. Nakon toga je potrebno da postavimo WinRM servis da se automatski startuje sa podizanjem sistema:

PSRemoting04

Sledeća stvar je izvršavanje PS skripti na računarima, možemo izabrati sve skriptove ili samo potpisane:

PSRemoting05

Ostalo je još da podesimo par pravila u firewall-u koji se odnose na WMI i WinRM:

PSRemoting06

PSRemoting07

U podešavanjima iznad možemo isključiti compatibility mode ukoliko u organizaciji imamo samo Win 7 i Server 2008R2

PSRemoting08

PSRemoting09

Pod svakim firewall pravilom imamo podešavanje opsega, pa možemo odrediti sa kojih se IP adresa ili koji se sve korisnici mogu povezati i za koje profile će se podešavanje odnositi.

PSRemoting10

Dodajemo pravilo i za WMI ako ćemo ga koristiti:

PSRemoting11

PSRemoting12

PSRemoting13

Sada možemo proveriti da li smo sve uspešno odradili sa komadnom:

 Invoke-Command -ComputerName imeRačunara -ScriptBlock {shutdown -r -t 10}

Provera da li i WMI radi korektno sa:

Get-WmiObject win32_bios -ComputerName imeRačunara -Credential (Get-Credential RAJCO\adminrajco)

Možemo koristiti i ovu funkciju za proveru portova:

function Test-Port{
     Param([string]$srv,$port=135,$timeout=3000,[switch]$verbose)
     $ErrorActionPreference = "SilentlyContinue"
     $tcpclient = new-Object system.Net.Sockets.TcpClient
     $iar = $tcpclient.BeginConnect($srv,$port,$null,$null)
     $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false)
     if(!$wait)
     {
         $tcpclient.Close()
         if($verbose){Write-Host "Connection Timeout"}
         Return $false
     }
     else
     {
         $error.Clear()
         $tcpclient.EndConnect($iar) | out-Null
         if($error[0]){if($verbose){write-host $error[0]};$failed = $true}
         $tcpclient.Close()
     }
     if($failed){return $false}else{return $true}
}

Pozivamo je sa:

Test-Port imeRačunara

Sa ovim smo završili podešavanje remotinga, a samim tim otvorili dosta mogućnosti i olakšali održavanje računara i servera.

Promena imena računara preko PowerShell-a

U sledećem postu ćemo videti kako promeniti ime računara preko powershell-a. Promenu imena ćemo prvo uraditi na lokalnom računaru, a zatim i na udaljenom. Ovo važi kako za računare učlanjene u domen tako i za računare u radnoj grupi.

Da bi promenili ime lokalnog računara potrebno je startovati PS kao administrator i iskopirati funkciju:

Function Rename-ComputerName ([string]$NewComputerName){
$ComputerInfo = Get-WmiObject -Class Win32_ComputerSystem
$ComputerInfo.rename($NewComputerName)}

Posle toga je potrebno pozvati Rename-ComputerName:

Rename-ComputerName rajco

Gde je rajco novo ime računara. Posle toga je ostalo da restartujemo računar i procedura preimenovanja je završena.

Ukoliko želimo da promenimo ime udaljenog računara bez da se logujemo na njega(što će najverovatnije i biti češći slučaj) možemo iskoristiti sledeće komande:

$credential = Get-Credential 
Get-WmiObject Win32_ComputerSystem -ComputerName staroIme -Authentication 6 | 
ForEach-Object {$_.Rename("novoIme",$credential.GetNetworkCredential().Password,$credential.Username)} 

Promenljiva credential je tu da bi nam sistem tražio korisničko ime i šifru, pošto ne bi bila najbolja praksa da u skriptu napišemo kredencijale.

Posle ovoga je ostalo još da restartujemo računar sa komadnom:

Get-WmiObject Win32_OperatingSystem -ComputerName staroIme | 
ForEach-Object {$_.Win32Shutdown(6)} 

Ukoliko posle ovih komandi dobijamo ReturnValue : 0 onda je sve u redu. Ukoliko se javi neka druga vrednost možete istražiti na google-u u čemu je problem.