Translate

среда, 21. март 2018.

Bekap DC na VmWare

Domen kontroler je virtualna masina na VmWare. Zbog DC potrebno je uraditi bekap tako da je instaliran Windows Server Backup feature i podesen System State Backup.

Greska koja se javila je:
Event ID: 517
The backup operation that started at '?2018?-?01?-?22T11:33:11.011224400Z' has failed with following error code '0x80780049'

Resenje:
REGEDIT

HKLM\SYSTEM\CurrentControlSet\Services\vsock

ImagePath    REG_EXPND_SZ
Ukoliko je vrednost: \SystemRoot\system32\drivers\vsock.sys

Promeniti u: system32\DRIVERS\vsock.sys

недеља, 17. септембар 2017.

Kreiranje lokalnih korisnika

Funkcija za kreiranje lokalnih korisnika

function create-localuser {
param($computer="localhost", $user, $password, [switch] $Admin)
$objOu = [ADSI]"WinNT://$computer"
$objUser = $objOU.Create("User", $user)
$objUser.setpassword($password)
$objUser.SetInfo()
$objUser.description = "User"
$objUser.SetInfo()
if($Admin){
Add-LocalGroupMember -Group Administrators -Member $user}
else{}
}


dodat je switch -Admin koji odredjuje da li ce korisnik biti dodat u grupu lokalnih administratora.

evo i primera kako je ja koristim

create-localuser -computer localhost -user ntest -password 123123123 -Admin

ili, ukoliko hocu vise korisnika

$users = import-csv C:\test\users.csv
foreach($user_full in $users){
$user = $user_full.user
$password = $user_full.password
create-localuser -user $user -password $password -Admin
}


struktura CSV fajla je
user,password

недеља, 23. октобар 2016.

FTP

Vec sam postavio skriptu za Upload na FTP sajt a evo sad i dodatne dve funkcije koje listaju fajlove na FTP serveru i brisu

function Get-FtpDir {
param($url, $credentials)
begin{

  $request = [Net.FtpWebRequest]::Create($url)
  if ($credentials) { $request.Credentials = $credentials }
  $request.Method = [System.Net.WebRequestMethods+FTP]::ListDirectory
  (New-Object IO.StreamReader $request.GetResponse().GetResponseStream()).ReadToEnd() -split "`r`n"
}}


function Remove-FtpFile{
param ($url, $credentials)
begin {
  $request = [System.Net.FtpWebRequest]::create($url)
  if ($credentials) { $request.Credentials =  $credentials }
  $request.Method = [System.Net.WebRequestMethods+Ftp]::DeleteFile
  [Void] $request.GetResponse()
}}


Primeri za koriscenje ovih funkcija su:

Get-FtpDir -url 'someftpaddress' -credentials get-credentials
Remove-FtpFile ("$ftpPath/FileName.txt") -credentials get-credentials


 

понедељак, 12. септембар 2016.

Provera korisnika u lokalnoj grupi

Evo jos jedna skripta, tj funkcija, na lokalnom ili udaljenom racunaru proverava sve korisnike u odredjenoj lokalnoj grupi i pravi listu.

1. citajuci ADSI proverava sve korisnike u grupi
2. za svakog lokalnog korisnika proverava opet ADSI i cita vrednosti
3. za svakog domenskog korisnika proverava u domenu vrednosti


function Get-GroupUsers {

    param(
    [Parameter(Mandatory=$true,valuefrompipeline=$true)]
    [string]$Compname, [string]$GroupName)
   
    begin {

foreach($computer in $Compname){



[ADSI]$group = "WinNT://$computer/$GroupName,group"
$members = $group.invoke("Members")
$found = ($members | measure).count

      if ($found -gt 0 ) {
        $members | foreach {
       
            $Hash = [ordered]@{Computername = $computer.toUpper()}
            $hash.Add("Name",$_[0].GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null))

            $ADSPath = $_[0].GetType().InvokeMember("ADSPath", 'GetProperty', $null, $_, $null)
            $hash.Add("ADSPath",$ADSPath)

            $hash.Add("Class",$_[0].GetType().InvokeMember("Class", 'GetProperty', $null, $_, $null)) 
   
            $hash.Add("Domain",$ADSPath.Split("/")[2])

            if ($ADSPath -match "/$computer/") {
                $local = $True
                }
            else {
                $local = $False
                }
            $hash.Add("IsLocal",$local)
$user = New-Object -TypeName PSObject -Property $hash
If($user.IsLocal -eq 'True'){
#################Local Users
$lusr = $user.name
$AllLocalAccounts = Get-WmiObject -Class Win32_UserAccount -ComputerName $computer -Namespace "root\cimv2" -filter "LocalAccount=True AND Name='$lusr'"
Foreach($LocalAccount in $AllLocalAccounts)
    {
[ADSI]$computerl="WinNT://$computer"
$LastLogin = $computerl.psbase.children | where {$_.name -eq "$lusr"} | select @{name="LastLogin";Expression={$_.psbase.properties.lastLogin}}
        $Object = New-Object -TypeName PSObject
        $Object|Add-Member -MemberType NoteProperty -Name "Computer Name" -Value $computer
        $Object|Add-Member -MemberType NoteProperty -Name "Name" -Value $LocalAccount.Name
        $Object|Add-Member -MemberType NoteProperty -Name "Full Name" -Value $LocalAccount.FullName
        $Object|Add-Member -MemberType NoteProperty -Name "Caption" -Value $LocalAccount.Caption
          $Object|Add-Member -MemberType NoteProperty -Name "Disabled" -Value $LocalAccount.Disabled
          $Object|Add-Member -MemberType NoteProperty -Name "Status" -Value $LocalAccount.Status
          $Object|Add-Member -MemberType NoteProperty -Name "LockOut" -Value $LocalAccount.LockOut
        $Object|Add-Member -MemberType NoteProperty -Name "Password Changeable" -Value $LocalAccount.PasswordChangeable
        $Object|Add-Member -MemberType NoteProperty -Name "Password Expires" -Value $LocalAccount.PasswordExpires
        $Object|Add-Member -MemberType NoteProperty -Name "Password Required" -Value $LocalAccount.PasswordRequired
        $Object|Add-Member -MemberType NoteProperty -Name "SID" -Value $LocalAccount.SID
        $Object|Add-Member -MemberType NoteProperty -Name "SID Type" -Value $LocalAccount.SIDType
        $Object|Add-Member -MemberType NoteProperty -Name "Account Type" -Value $LocalAccount.AccountType
        $Object|Add-Member -MemberType NoteProperty -Name "Domain" -Value $LocalAccount.Domain
        $Object|Add-Member -MemberType NoteProperty -Name "Description" -Value $LocalAccount.Description
        $Object|Add-Member -MemberType NoteProperty -Name "Type" -Value 'Local User'
        $Object|Add-Member -MemberType NoteProperty -Name "Last Login" -Value $LastLogin.lastlogin
        $Object
}

}else{
#################Domain Users

$lusr = $user.Name
$domainUser = Get-ADUser $lusr    -ErrorAction SilentlyContinue
$userProp = Get-ADUser $lusr -Properties * -ErrorAction SilentlyContinue
$Object1 = New-Object -TypeName PSObject
if(($domainUser.Enabled) -eq 'true'){$dis = 'False'}else{$dis = 'True'}
if(($userProp.CannotChangePassword) -eq 'True'){$changepass = 'False'}else{$changepass = 'True'}
if(($userProp.PasswordNeverExpires) -eq 'True'){$pasexp = 'False'}else{$pasexp = 'True'}
if(($userProp.PasswordNotRequired) -eq 'True'){$pasreq = 'False'}else{$pasreq = 'True'}
if(($userProp.isDeleted) -eq 'True'){$stat = 'Deleted'}else{$stat = 'OK'}
if(($userProp.Description) -eq 'True'){$stat = 'Deleted'}else{$stat = 'OK'}
        $Object1|Add-Member -MemberType NoteProperty -Name "Computer Name" -Value $computer
        $Object1|Add-Member -MemberType NoteProperty -Name "Name" -Value $domainUser.Name
        $Object1|Add-Member -MemberType NoteProperty -Name "Full Name" -Value $domainUser.UserPrincipalName
        $Object1|Add-Member -MemberType NoteProperty -Name "Caption" -Value $domainUser.SamAccountName
          $Object1|Add-Member -MemberType NoteProperty -Name "Disabled" -Value $dis
          $Object1|Add-Member -MemberType NoteProperty -Name "Status" -Value $stat
          $Object1|Add-Member -MemberType NoteProperty -Name "LockOut" -Value $userProp.LockedOut
        $Object1|Add-Member -MemberType NoteProperty -Name "Password Changeable" -Value $changepass
        $Object1|Add-Member -MemberType NoteProperty -Name "Password Expires" -Value $pasexp
        $Object1|Add-Member -MemberType NoteProperty -Name "Password Required" -Value $pasreq
        $Object1|Add-Member -MemberType NoteProperty -Name "SID" -Value $domainUser.SID.Value
        $Object1|Add-Member -MemberType NoteProperty -Name "SID Type" -Value 'No Data'
        $Object1|Add-Member -MemberType NoteProperty -Name "Account Type" -Value $userProp.sAMAccountType
        $Object1|Add-Member -MemberType NoteProperty -Name "Domain" -Value (Get-ADDomain).forest
        $Object1|Add-Member -MemberType NoteProperty -Name "Description" -Value $userProp.Description
        $Object1|Add-Member -MemberType NoteProperty -Name "Type" -Value 'Domain User'
        $Object1
        }



         }

}
else{}

}}}


parametri funkcije su naziv racunara i naziv lokalne grupe.

Primer:
Get-GroupUsers -Compname $env:COMPUTERNAME -GroupName 'administrators'

петак, 29. јануар 2016.

Public ip skripta

Ukoliko imate klijenta ili održavate udaljenu lokaciju koja nema statičku ip adresu, ili jednostavno imate potrebu da uvek znate spoljnu adresu određene mreže, u nastavku se nalazi jednostavna powershell skripta koja će vas obavestiti svaki put kada dodje do promene.

Pošto na nivou operativnog sitema račnara koji se nalazi u određenom LAN-u ne postoji način da se dođe do javne ip adrese te mreže, ova skripta poziva WebAPI (https://api.ipify.org) koji vraća ip adresu sa kojeg je HTTP_Request stigao (javnu ip adresu vaše mreže ukoliko se ne nalazite iza proksija) a zatim upoređuje sa lokalno sačuvanom adresom iz prethodne provere. Ukoliko adrese nisu iste, poslaće email obaveštenje sa detaljima o novoj ip adresi.

#Putanja do fajla u kom se čuva ip adresa iz poslednje provere
$filePath = "ip.txt" 
$Old_IP = ''

$From = "sender@gmail.com"
$To = "receiver@gmail.com"
$Subject = "Ip changed"
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
$SMTPClient.EnableSsl = $true 
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("email username", "email password"); 

#blok koji proverava da li postoji fajl ip.txt na odredjenoj lokaciji
 ukoliko nema kreira novi prazan fajl (da bi i prilikom prvog pokretanja skripte poslao obaveštenje) a ukoliko postoji uzima njegov sadržaj (ip iz poslednje provere)
if(!(Test-Path -Path $filePath))
  {
   new-item -Path $filePath –itemtype file
  }
else
  {
$Old_IP = Get-Content $filePath
  }
#Pozivanje WebApi-ja koji vraća trenutnu javnu ip adresu
$url = 'https://api.ipify.org?format=json'
$Http_request =  Invoke-RestMethod -Uri $url
$Curent_IP = $Http_request.ip 

#Proverava adresu iz fajla sa preuzetom adresom
if($Old_IP -ne $Curent_IP){
$Curent_IP | Out-File ip.txt
$SMTPMessage = New-Object System.Net.Mail.MailMessage($From,$To,$Subject, $Curent_IP)
$SMTPClient.Send($SMTPMessage)
}


четвртак, 28. јануар 2016.

skripta za monitoring web resursa

Dostupnost Web stranice, WebAPI-ja/Servisa ili bilo kog drugog resursa  koji hostujete na Webu-u je izuzetno kritična i važna stavka u administraciji sistema. Zbog Marfijevog zakona, u jednom trenutku će se desiti da Web resursi jednostavno postanu nedostupni iz nepoznatog razloga, a vi nećete ni biti svesni dok telefoni ne počnu da zvone.

U nastavku se nalazi primer skripte koja služi kao monitoring, log i alert sistem koja može da prati dostupnost i vreme odziva bilo kog resursa na webu, šalje email obaveštenje o statusu i upisuje log u bazu. U mom slučaju i ovom primeru skripta nadgleda Web Servise

#U mom slučaju pristup bilo kom Web servisu zahteva Log-In sekvencu koja vraća token za autentifikaciju tako da sam ja na samom početku skripte pozvao LoginServis sa mojim kredencijalima pomoću cmdleta Invoke-RestMethod koji automatski parsira JSON formatirane stringove i njihove vrednosti pakuje u ps objekte

$Login = Invoke-RestMethod -Uri http://mojLoginUrlServis?Username=mojusername"&"Password=mojpass

#Moj username i accsess Token za pozivanje drugih Servisa dobijeni Login sekvencom
$Token = $Login.Token
$Username = $Login.Username

#Dodatni parametri koji zahtevaju WebServisi
$Params = @{username = $Username;token=$Token;page = 0;Delatnost='ninja';Grad="Beograd"}

$datetime = ' '

#Podešavanja email klijenta
$From = "sender@gmail.com" 
$To = "receiver@gmail.com"
$Subject = "Web API is offline"
$SMTPServer = "smtp.gmail.com"
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
$SMTPClient.EnableSsl = $true 
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential("email-username", "email-password");
$Body = ""
$SendMail = 0

$HTTP_Status = ' '

#.txt fajl u kom se nalaze putanje do resursa koji se nadgledaju 
$content = Get-Content -Path "url.txt"

$conn = New-Object System.Data.SqlClient.SqlConnection
#SQL connecton string 
$conn.ConnectionString = "Data Source=xxx.xxx.xxx.xxx; Initial Catalog = DbName; User ID = DbUser; Password = DbPassword"

$conn.open()

foreach ($url in $content) {
    $datetime = Get-Date 
#Merenje vremena odziva Servisa
    $time =  Measure-Command -Expression {
    try { 

       $HTTP_Request =  Invoke-WebRequest -Uri $url -Body $params -ErrorAction SilentlyContinue
       $HTTP_Status = $HTTP_Request.StatusCode

#U ps-u ako HTTPREQUEST vrati rezultat različit od 200 (200 = Servis je dostupan), rezultat se tretira kao exception i skripta puca ukoliko se na cmdletu koji izaziva grešku ne postavi -ErrorAction SilentlyContinue
    
                 $online = 1       
    }
    catch {

#Blok koji hendluje grešku i kreira tekst email obaveštenja a takodje uzima i ResponseCode koji pomaže prilikom dijagnostikovanja greške

    $HTTP_Status = $_.Exception.Response.StatusCode.Value__
    $Body = $Body + "Webservice: " + $url + " is offline Time:"+ $datetime + " Reason: " +  $_.Exception.Response.StatusCode.Value__ + "r`n"                
                    $online = 0     
         }
     }

 #Upisivanje log-a u Bazu
    $response_time = $time.TotalSeconds
    $cmd = New-Object System.Data.SqlClient.SqlCommand
    $cmd.connection = $conn
    $cmd.CommandText = "INSERT INTO Monitoring (Url,Online,Response_time,Date,Response_code) VALUES('{0}','{1}','{2}','{3}','{4}')" -f $url,$online,$response_time,$datetime,$HTTP_Status
    $cmd.ExecuteNonQueryAsync() | Out-Null 
}
  if($SendMail -eq 1){
 #Slanje email notifikacije
         $SMTPMessage = New-Object System.Net.Mail.MailMessage($From,$To,$Subject,$Body)
         $SMTPClient.Send($SMTPMessage)

        }
  $conn.Close()



субота, 23. јануар 2016.

FTP servis u PowerShell-u

Evo neceg sto sam nedavno pisao.

Rec je o powershell skripti koja nadgleda odredjeni folder i cim se pojavi *.xml fajl uradi upload na ftp server.

while($true){
$configfilePath = 'E:\ftpxml\config.xml'
$settings = [xml](get-content $configfilePath)
$podesavanja = $settings.RootElement.ftp

###Log file
$LogFileName = (get-date).ToString("yyyyMMdd")
$logFile = "E:\ftpxml\Log\ftp_upload_$LogFileName.log"

$ftpaddress = $podesavanja.ftpaddress
$ftpuser = $podesavanja.username
$ftppass = $podesavanja.password
$copyfrom = $podesavanja.FolderA
$copytoo = $podesavanja.FolderB
$sleep = $podesavanja.waittime
$ftptime = $podesavanja.ftptime

$ftp = "ftp://$ftpaddress/"
$webclient = New-Object System.Net.WebClient
$webclient.Credentials = New-Object System.Net.NetworkCredential($ftpuser,$ftppass) 

foreach($item in (dir $copyfrom -Include *.xml)){
    Start-Sleep -Seconds $ftptime
    $uri = New-Object System.Uri($ftp+$item.Name)
    $webclient.UploadFile($uri, $item.FullName)
    if($?){
    $uploadtime = Get-Date
    Add-Content $logFile "$uploadtime File $item Uploaded"
    Copy-Item $item.FullName $copytoo
    if((Test-Path "$copytoo\$item") -eq 'True'){
    $copytime = Get-Date
    Add-Content $logFile "$copytime File $item Copyed"
    Remove-Item $item.FullName
    $removetime = Get-Date
    Add-Content $logFile "$removetime File $item Deleted from Source Folder"
    }
    }
 }
 Start-Sleep -Seconds $sleep
 }



 Sva podesavanja su u *.xml fajlu koji izgleda:

<?xml version="1.0"?>
<?xml-stylesheet type='text/xsl' href='style.xsl'?>
<RootElement>
    <ftp>
        <ftpaddress>ftpServerAdresa:21</ftpaddress>
        <username>ftpuser</username>
        <password>ftppassword</password>
        <FolderA>C:\test1</FolderA>
        <FolderB>C:\test2</FolderB>
        <waittime>60</waittime>
        <ftptime>60</ftptime>
    </ftp>
</RootElement>


Tako da skripta cita sva podesavanja sa xml fajla, nadgleda FolderA i cim se pojavi *.xml fajl uploaduje na ftp server i zatim kopira fajl u FolderB

u 22. redu skripte se nalazi deo
foreach($item in (dir $copyfrom -Include *.xml)){

gde mozete da izmenite da gleda bilo koju drugu ekstenziju ili ukoliko se ukloni -include *.xml gleda sve fajlove u FolderA.

Sve sto se desi, loguje se u folderu koji je definisan u 8. redu
$logFile = "E:\ftpxml\Log\ftp_upload_$LogFileName.log"
 tako da bi vam skripta radila vi treba da promenite putanju LOG fajla kao i putanju config fajla u 2. redu.

Ja sam u svakom slucaju skriptu bildovao kao Windows Servis uz pomoc PowerGUI-a