Vmware PowerCLI finding VM and Datastore

Posted Posted in Vmware

If you are looking for a VM datastore with Vmware PowerCLI below is a very usefull code to check :

get-vm | select name , @{N="Datastore";E={[string]::Join(',',(Get-Datastore -Id $_.DatastoreIdList | Select -ExpandProperty Name))}}

This is going to show you all the VMs and their datastore , but you can also put name of a VM in front of get-vm command.

Recover passwords in Microsoft active directory Group policy object

Posted Posted in Microsoft

Recover passwords in Microsoft active directory  Group policy object

Becarefull about putting passwords in Microsoft group policy

I can remember the old days that we use to use scripts for changing local administrator account password on all domain members PCs or adding a user by scripts, it was a simple batch file with the net user command but after a while Microsoft came out with the preferences in the group policy and we were happy with that how easily we can add a new user or update one and dealing with the password stuff!!  yup all of them are really good and the second one is easy to use but don’t forget security! putting passwords in group policy is dangerous this is the thing that I always mention in the whole of my professional life in IT industry and still I can see it among different people, you know what people do not pay attention to the alert! although Microsoft removed the ability to deal with password in the preferences ,but even in the old days when you wanted to configure the password stuff in the preferences there was an alert mentioning that this is a security vulnerability,

in this post I am going to show you some information gathering from different places about how insecure the passwords are in the group policy even when they are hashed.

Every IT pro should know that all authenticated users have read-only access to all the object in active directory domain environment so all the standard users can see the Group policy objects (GPO) in the active directory as you know they are located in \\domain-name\sysvol  and also if a  user can install the remote server administration tools (RSAT) on their computers , they can see the GPOs from group policy management console GPMC!

So i know that you are thinking of passwords in GPOs ! yes every users in the domian can read the passwords! yup but maybe they are encrypted , the answer is yes and no 🙂 we should break this methodologies into 2 categories :

1-If you configure a batch file and want to apply it as a script from GPO, definately the password is in the clear text and every one inside your domian can see that .

2-If you use the preferences , when you follow the GPO in the SYSVOL folder you’ll see the password is encrypted in a XML file some thing like this :


<?xml version=”1.0″ encoding=”utf-8″?>
<Groups clsid=”{3125E937-EB16-4b4c-9934-544FC6D24D26}”>
<User clsid=”{DF5F1855-51E5-4d24-8B1A-D9BDE98BA1D1}” name=”LocalTestUser” image=”0″ changed=”2013-07-04 00:07:13″ uid=”{47F24835-4B58-4C48-A749-5747EAC84669}”>
<Properties action=”C” fullName=”” description=”” cpassword=”sFWOJZOU7bJwICaqvmd+KAEN0o4RcpxxMLWnK7s7zgNR+JiJwoSa+DLU3kAIdXc1WW5NKrIjIe9MIdBuJHvqFgbcNS873bDK2nbQBqpydkjsbsPXV0HRPpQ96phie6N9tn4NF3KYyswokkDnj8gvuyZBXqoG94ML8/jhe37eHJiZGyi5IBoPuCfKpurj2″ changeLogon=”0″ noChange=”0″ neverExpires=”0″ acctDisabled=”0″ userName=”LocalTestUser”/>
</User>
</Groups>

So there is a password filed and you can see the password is hashed, yup but there is a minor problem with this method of encryption and the problem is, the private key for this password encryption is publicly announced by Microsft in MSDN: https://msdn.microsoft.com/en-us/library/cc422924.aspx

So when we have the cipher text(cpassword) that encrypted by public key , then we can decrypt it by the private key which is available in the MSDN , yes pretty simple definitely we need some code here but if you search on the internet you can probably find something I am going to share one of them here :

open notepad , copy and paste the below code into it and save it as Get-GPPPassword.ps1 name


function Get-GPPPassword {

    
    [CmdletBinding()]
    Param ()
    
    #Some XML issues between versions
    Set-StrictMode -Version 2
    
    #define helper function that decodes and decrypts password
    function Get-DecryptedCpassword {
        [CmdletBinding()]
        Param (
            [string] $Cpassword 
        )

        try {
            #Append appropriate padding based on string length  
            $Mod = ($Cpassword.length % 4)
            
            switch ($Mod) {
            '1' {$Cpassword = $Cpassword.Substring(0,$Cpassword.Length -1)}
            '2' {$Cpassword += ('=' * (4 - $Mod))}
            '3' {$Cpassword += ('=' * (4 - $Mod))}
            }

            $Base64Decoded = [Convert]::FromBase64String($Cpassword)
            
            #Create a new AES .NET Crypto Object
            $AesObject = New-Object System.Security.Cryptography.AesCryptoServiceProvider
            [Byte[]] $AesKey = @(0x4e,0x99,0x06,0xe8,0xfc,0xb6,0x6c,0xc9,0xfa,0xf4,0x93,0x10,0x62,0x0f,0xfe,0xe8,
                                 0xf4,0x96,0xe8,0x06,0xcc,0x05,0x79,0x90,0x20,0x9b,0x09,0xa4,0x33,0xb6,0x6c,0x1b)
            
            #Set IV to all nulls to prevent dynamic generation of IV value
            $AesIV = New-Object Byte[]($AesObject.IV.Length) 
            $AesObject.IV = $AesIV
            $AesObject.Key = $AesKey
            $DecryptorObject = $AesObject.CreateDecryptor() 
            [Byte[]] $OutBlock = $DecryptorObject.TransformFinalBlock($Base64Decoded, 0, $Base64Decoded.length)
            
            return [System.Text.UnicodeEncoding]::Unicode.GetString($OutBlock)
        } 
        
        catch {Write-Error $Error[0]}
    }  
    
    #define helper function to parse fields from xml files
    function Get-GPPInnerFields {
    [CmdletBinding()]
        Param (
            $File 
        )
    
        try {
            
            $Filename = Split-Path $File -Leaf
            [xml] $Xml = Get-Content ($File)

            #declare empty arrays
            $Cpassword = @()
            $UserName = @()
            $NewName = @()
            $Changed = @()
            $Password = @()
    
            #check for password field
            if ($Xml.innerxml -like "*cpassword*"){
            
                Write-Verbose "Potential password in $File"
                
                switch ($Filename) {

                    'Groups.xml' {
                        $Cpassword += , $Xml | Select-Xml "/Groups/User/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/Groups/User/Properties/@userName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $NewName += , $Xml | Select-Xml "/Groups/User/Properties/@newName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/Groups/User/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                    }
        
                    'Services.xml' {  
                        $Cpassword += , $Xml | Select-Xml "/NTServices/NTService/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/NTServices/NTService/Properties/@accountName" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/NTServices/NTService/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                    }
        
                    'Scheduledtasks.xml' {
                        $Cpassword += , $Xml | Select-Xml "/ScheduledTasks/Task/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/ScheduledTasks/Task/Properties/@runAs" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/ScheduledTasks/Task/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                    }
        
                    'DataSources.xml' { 
                        $Cpassword += , $Xml | Select-Xml "/DataSources/DataSource/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/DataSources/DataSource/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/DataSources/DataSource/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}                          
                    }
                    
                    'Printers.xml' { 
                        $Cpassword += , $Xml | Select-Xml "/Printers/SharedPrinter/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/Printers/SharedPrinter/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/Printers/SharedPrinter/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                    }
  
                    'Drives.xml' { 
                        $Cpassword += , $Xml | Select-Xml "/Drives/Drive/Properties/@cpassword" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $UserName += , $Xml | Select-Xml "/Drives/Drive/Properties/@username" | Select-Object -Expand Node | ForEach-Object {$_.Value}
                        $Changed += , $Xml | Select-Xml "/Drives/Drive/@changed" | Select-Object -Expand Node | ForEach-Object {$_.Value} 
                    }
                }
           }
                     
           foreach ($Pass in $Cpassword) {
               Write-Verbose "Decrypting $Pass"
               $DecryptedPassword = Get-DecryptedCpassword $Pass
               Write-Verbose "Decrypted a password of $DecryptedPassword"
               #append any new passwords to array
               $Password += , $DecryptedPassword
           }
            
            #put [BLANK] in variables
            if (!($Password)) {$Password = '[BLANK]'}
            if (!($UserName)) {$UserName = '[BLANK]'}
            if (!($Changed)) {$Changed = '[BLANK]'}
            if (!($NewName)) {$NewName = '[BLANK]'}
                  
            #Create custom object to output results
            $ObjectProperties = @{'Passwords' = $Password;
                                  'UserNames' = $UserName;
                                  'Changed' = $Changed;
                                  'NewName' = $NewName;
                                  'File' = $File}
                
            $ResultsObject = New-Object -TypeName PSObject -Property $ObjectProperties
            Write-Verbose "The password is between {} and may be more than one value."
            if ($ResultsObject) {Return $ResultsObject} 
        }

        catch {Write-Error $Error[0]}
    }
    
    try {
        #ensure that machine is domain joined and script is running as a domain account
        if ( ( ((Get-WmiObject Win32_ComputerSystem).partofdomain) -eq $False ) -or ( -not $Env:USERDNSDOMAIN ) ) {
            throw 'Machine is not a domain member or User is not a member of the domain.'
        }
    
        #discover potential files containing passwords ; not complaining in case of denied access to a directory
        Write-Verbose 'Searching the DC. This could take a while.'
        $XMlFiles = Get-ChildItem -Path "\\$Env:USERDNSDOMAIN\SYSVOL" -Recurse -ErrorAction SilentlyContinue -Include 'Groups.xml','Services.xml','Scheduledtasks.xml','DataSources.xml','Printers.xml','Drives.xml'
    
        if ( -not $XMlFiles ) {throw 'No preference files found.'}

        Write-Verbose "Found $($XMLFiles | Measure-Object | Select-Object -ExpandProperty Count) files that could contain passwords."
    
        foreach ($File in $XMLFiles) {
            $Result = (Get-GppInnerFields $File.Fullname)
            Write-Output $Result
        }
    }

    catch {Write-Error $Error[0]}
}

> run as admin the PowerShell in one of the domain members computer and

>check your PowerShell execution policy by Get-ExecutionPolicy  command  the best setting is RemoteSigned 

>if it is not this change it by the set-executionpolicy remotesigned command

> change the directory to the location of Get-GPPassword.ps1 file and

>run import-module .\Get-GPPPassword.ps1

>after that run Get-GPPPassword  without any extension

Voala now excavate the output and you’ll definitely find some useful information 🙂

Netapp New Features insight 2018

Posted Posted in Netapp

In this post, I’d like to talk about Netapp New features in insight 2018

First of all , In NetApp’s annual three-day technical training conference, attendees heard more about becoming a data visionary. 

So , Netapp focus was more on Cloud solutions  and one of the new was Kubernetes and Netapp and The stackpoint.io Kubernetes-as-a-service platform combined with NetApp’s Cloud Data Services creates a complete DevOps solution, so customers can focus on innovation, not administration.

So Below is a summary of the new features :

  • Cloud insight
    • With dynamic topology and correlation analysis
    • Identifying abandoned and unused resources to right size
    • Get advanced analytics and machine learning to identify issues before they become critical outages
  • Azure Netapp Files
    • NFS storage right in the Azure portal
    • REST API support, CLI access
  • Cloud Volumes Service for AWS
  • Introducing new HCI Compute Nodes with new switches
  • Ansible module for Netapp
  • Flash-Accelerated object storage for IoT
  • StorageGrid SG6060 Appliance
  • MAX Data
    • Nanoseconds latency using PMEM
    • For latency-sensitive apps and DBs
  • Snapmirror strict synchronous/synchronous
  • MetroCluster Enhancements
    • Maximum distance increased to 700km
    • Application must be able to tolerate up to 10 ms write acknowledgment latency
  • SVM DR  from MetroCluster
  • Netapp ONTAP AI
  • NetApp Data Availability Services (NDAS)

 

consequently :

In a simple sentence, I’d say there is a tremendous amount of work for cloud solutions!

Finally , Make sure that you are in touch with Social media at the bottom of my Homepage