Tuesday, January 26, 2016

List account configured on logon of Windows Service - Powershell

Maintaining best practices on windows best thing, but when someone configures it incorrectly, it is hard to track those mis-configured item., you have to check through all the settings in documents and it is manually time consuming boring task. I had a scenario where other engineer used his username password on local services account in Services, and he left the organization or is on leave (password expired), causing  services to stop, and critical application is down in the absence of user, and you have to take all the heat.
Here is the script, helps to find or list accounts configured in the windows services. and are the following parameters to the scripts.
-ComputerName: If not specified default is localhost
-Service: if not specified default is lanmanserver, you have mention service name not display name

-Credential: Incase if remote computer in another domain or if you are not administrator you can use "-credential (get-credential)" to connect. otherwise for same domain this parameter doesn't required.
-Protocol: By default it uses legacy wmi dcom protocol to connect, there is another option wsman which use PSRemoting protocol.
 function Get-ServiceAccount {  
 <#  
  .Synopsis  
   Get the log on account configured in windows service.  
  .Description  
   The Get-ServiceAccount command collects log on account user configured in windows service. you will have to use servicename (not service display name) in the service parameter  
  .Example  
   Get-ServiceAccount  
   It will show log on account configured of the lanmanserver service.  
  .Example  
   "ServiceName" | Get-ServiceAccount  
   Cat c:\temp\Computerlist.txt | Get-ServiceAccount  
   Get-ServiceAccount is capable of taking output pipeline.  
   Get-ServiceAccount -Service wuauserv -Credential (Get-Credential) -ComputerName Server001  
   ∞ Server001 is pinging, attempting to connect...  
   PSComputerName : Server001  
   Name      : wuauserv  
   DisplayName  : Windows Update  
   StartMode   : Manual  
   State     : Running  
   Started    : True  
   StartName   : LocalSystem  
  .Example  
   Get-ServiceAccount -Service wuauserv -Credential (Get-Credential) -ComputerName Server001 -Protocol WSMAN   
   It collects the information using wsman protocol  
  .Example  
   "Server001", "server002", "Server003" | foreach {Get-ServiceAccount -Service someservice -ComputerName $_}  
   Get-Content -Path c:\temp\serverlist.txt | foreach {Get-ServiceAccount -Service someservice -ComputerName $_}  
   you can use it to featch information from multiple computers.  
  .Example  
   $cred = (Get-Crendential)  
   "Server001", "Server002" | foreach {Get-ServiceAccount -Computer $_ -Credential $cred -Service someservice}  
   Servers can be passed from array or files, and you can specify crendetials  
  .Parameter ComputerName  
   It is Alias to Name parameter  
   if kept blank by default will collect information about Localhost.  
  .Parameter Service  
   if kept blank by default will collect information about lanmanserver.  
  .Inputs  
   [string]  
  .OutPuts  
   Get-ServiceAccount -Service wuauserv -Credential (Get-Credential) -ComputerName 192.168.33.51  
   cmdlet Get-Credential at command pipeline position 1  
   Supply values for the following parameters:  
   ∞ 192.168.33.51 is pinging, attempting to connect...  
   PSComputerName : 192.168.33.51  
   Name      : wuauserv  
   DisplayName  : Windows Update  
   StartMode   : Manual  
   State     : Running  
   Started    : True  
   StartName   : LocalSystem  
  .Notes  
   NAME: Get-ServiceAccount  
   AUTHOR: Kunal Udapi  
   LASTEDIT: 26th August 2015  
   KEYWORDS: Service log on accounts  
  .Link  
   #Check Online version: Http://kunaludapi.blogspot.com   
   #Requires -Version 3.0  
  #>  
 #requires -Version 3   
 [CmdletBinding(SupportsShouldProcess)]  
 Param(  
   [Parameter(<#Mandatory=$true,#>Position=1,  
     ValueFromPipeline=$true,  
     ValueFromPipelineByPropertyName=$true)]  
   [AllowNull()]  
   [alias("ComputerName", "Computer")]  
   [string]$Name = $env:COMPUTERNAME,   
   [Parameter(Position=2)]  
   [AllowNull()]    
   [alias("ServiceName")]  
   [string]$Service = 'LanmanServer',  
   <#[Parameter(Mandatory=$true)]#$Credential#>  
   [System.Management.Automation.PSCredential]$Credential,  
   #[String]$CSVfile = "C:\Temp\ServiceDetails.csv",  
   $Protocol = 'DCOM'  
 ) #Param  
 Begin {  
   #$TempFolder = Split-Path $CSVfile  
   #if (-not (Test-Path $TempFolder)) {  
   #  [void](New-Item -Path $TempFolder -Force)  
   #} #if (-not (Test-Path $TempFolder)) {  
 #region Ping  
   Function Get-Ping {  
     Test-Connection -ComputerName $Name -Quiet -Count 2 -ErrorAction SilentlyContinue  
   } # Function Ping-Server  
 #endregion  
   $CIMoption = New-CimSessionOption -Protocol $protocol  
 } #Begin  
 Process {  
   $query = "Select * from Win32_Service Where Name = `'$service`'"  
   if ($(Get-Ping $Name) -eq $true) {  
     Write-Host "$([char]8734) $Name is pinging, attempting to connect..." -ForegroundColor Green  
     if ($Credential -eq $null) {  
       Try {  
         #$ServiceDetails = Get-WmiObject -Query $query -ComputerName $Name -ErrorAction SilentlyContinue  
         $CIMsession = New-CimSession -ComputerName $Name -SessionOption $CIMoption -ErrorAction SilentlyContinue  
         $ServiceDetails = Get-CimInstance -CimSession $CIMsession -Query $query  
       } #Try  
       Catch {  
         Write-Host "`t $([char]215) Server $Name cannot be contacted, skipped it" -ForegroundColor Red  
         Continue  
       } #Catch  
     } #if ($Credential -eq $null)  
     else {  
       Try {  
         #$ServiceDetail = Get-WmiObject -Query $query -ComputerName $Name -Credential $Credential -ErrorAction SilentlyContinue  
         $CIMsession = New-CimSession -ComputerName $Name -SessionOption $CIMoption -Credential $Credential -ErrorAction SilentlyContinue  
         $ServiceDetails = Get-CimInstance -CimSession $CIMsession -Query $query  
       } #Try  
       Catch {  
         Write-Host "`t $([char]215) Server $Name cannot be contacted, skipped it" -ForegroundColor Red  
         Continue  
       } #Catch  
     } #else ($Credential -eq $null)  
   } #if ($(Ping-Server $Name) -eq $true  
   else {  
     Write-Host "$([char]8734) $Name is not pinging, but Still trying to connect..." -ForegroundColor Yellow  
     if ($Credential -eq $null) {  
       Try {  
         #$ServiceDetail = Get-WmiObject -Query $query -ComputerName $Name -ErrorAction SilentlyContinue  
         $CIMsession = New-CimSession -ComputerName $Name -SessionOption $CIMoption -ErrorAction SilentlyContinue  
         $ServiceDetails = Get-CimInstance -CimSession $CIMsession -Query $query  
       } #Try  
       Catch {  
         Write-Host "`t $([char]215) Server $Name cannot be contacted, skipped it" -ForegroundColor Red  
         Continue  
       } #Catch  
     } #if ($Credential -eq $null)  
     else {  
       Try {  
         #$ServiceDetail = Get-WmiObject -Query $query -ComputerName $Name -Credential $Credential -ErrorAction SilentlyContinue  
         $CIMsession = New-CimSession -ComputerName $Name -SessionOption $CIMoption -Credential $Credential -ErrorAction SilentlyContinue  
         $ServiceDetails = Get-CimInstance -CimSession $CIMsession -Query $query  
       } #Try  
       Catch {  
         Write-Host "`t $([char]215) Server $Name cannot be contacted, skipped it" -ForegroundColor Red  
         Continue  
       } #Catch  
     } #else ($Credential -eq $null)  
   } #else ($(Ping-Server $Name) -eq $false)  
   if (-not ($ServiceDetails -eq $null)) {  
     $ServiceDetails | Select-Object PSComputerName, Name, DisplayName, StartMode, State, Started, StartName  
   } #if ($ServiceDetails -eq $null)  
   else {  
     Write-Host "`t $([char]215) Please check Server $Name manually" -ForegroundColor Red  
   } #else ($ServiceDetail -eq $null)  
 } #Process  
 End {  
 } #End  
 } $function  
 Get-ServiceAccount   
Using this script is fairly simple you can copy paste this code in Powershell profile, on how to use powershell profile you can check my another post here., In case if you don,t want to save it in profile, you can copy paste it in text file and rename extension to .ps1. and on the last line of .ps1 file put line Get-ServiceAccount to execute this function, and execute it in powershell doing dot sourcing file ie: .\script.ps1 (Before executing make sure you have run as administrator powershell and Set-ExecutionPolicy RemoteSigned (or bypass or unrestricted))

Here is the example how I can use this script for multiple servers
$cred = Get-Credential 
Get-Content -Path c:\temp\Serverslist.txt |  #Serverslist.txt contains list of servers
    foreach {Get-ServiceAccount -Credential $cred -ComputerName $_ -Service someservice} | 
        Export-Csv -NoTypeInformation -Path c:\temp\ServiceInfo.csv 
#You will need to make changes at the text marked in orange as per your need.

Above are some of the screenshots, checke out my next script changing username and password of the service logon. 
Other useful scripts:
Get members from Remote Groups

Wednesday, January 20, 2016

Importing VM annotation (Attributes) and notes from CSV file into vCenter - Powercli

As in the earlier blog after exporting VM annotations, notes and other useful information to CSV/excel file, It was time to Import those information on new vCenter, This new vCenter has new Esxi Server connected from old vCenter, and when I check Virtual Machine tab at the right side on the esxi, I don't see any Information which I had present from old vCenter.
I created VM annotation attributes, just to show you how data is missing and everything is blank., This how you miss value vm annotation information after moving esxi to another vcenter
This information can be filled with below script.
 function Import-VMAnnotation {  
 <#   
 .SYNOPSIS   
 Import VM information Annotation, Notes into VM Attributes  
 .DESCRIPTION   
 The function set Annotation, Notes on VM into vcenter, you will require Export-VMAnnotation function to export data into CSV file.  
 .NOTES    
 Author: Kunal Udapi   
 http://kunaludapi.blogspot.com   
 .PARAMETER N/a   
 No Parameters Required   
 .EXAMPLE   
 PS> Import-VMAnnotation -CSV c:\Temp\VMCMDB.csv   
 #>   
 [CmdletBinding()]  
 #####################################    
 ## ## Version: 1    
 ## Tested this script on successfully   
 ## 1) Powershell v4    
 ## 2) Windows 8.1  
 ## 3) vSphere 5.5 (vcenter, esxi)  
 ## 4) powercli 6.0  
 #####################################    
 Param (  
   [Parameter(Mandatory=$true, Position=0)]   
   [ValidateNotNullOrEmpty()]   
   [string]$CSV  
 )  
   Begin{  
    if (-not(Get-PSSnapin vmware.vimautomation.core -ErrorAction SilentlyContinue)) {   
     Add-PSSnapin vmware.vimautomation.core   
    } #if   
   } #Begin  
   Process{  
     $vmlist = Import-Csv $CSV  
     $NonRequiredProperties = ""  
     $properties = $vmlist | Get-Member -MemberType NoteProperty | Where-Object {($_.name -ne "VMName") -and ($_.name -ne "PowerState") -and ($_.name -ne "IPAddress") -and ($_.name -ne "FolderPath") -and ($_.name -ne "Notes")} | Select -ExpandProperty Name  
     $CustomAttributes = Get-CustomAttribute -TargetType VirtualMachine  
     foreach ($NotExist in $properties) {  
       if (!($CustomAttributes.Name -contains $Notexist)) {  
         Write-Host -BackgroundColor Yellow -ForegroundColor Black "###Custom Attribute `"$NotExist`" does not exist Creating it###"  
         [void](New-CustomAttribute -Name $NotExist -TargetType VirtualMachine)  
       } #if (-Not($CustomAttributes -contains $Notexist))  
       else {  
         Write-Host -BackgroundColor DarkGreen "###Custom Attribute `"$NotExist`" exists, Skipping it###"  
       } #else (!($CustomAttributes.Name -contains $Notexist))  
     } #foreach ($NotExist in $properties)  
     Foreach ($VMObj in $VMList) {  
       $vm = Get-VM $VMObj.VMName  
       #$VMObj.VMName  
       Write-Host -BackgroundColor DarkGreen "`t###Adding Notes and Annotation on Virtual Machine `"$Name`"###"  
       [void]($vm | Set-VM -Notes $($VMObj.notes) -Confirm:$false)  
       $Name = $vm.name  
       Foreach ($Prop in $properties) {  
         $PropValue = $VMObj.$prop        
           Write-Host -BackgroundColor Yellow -ForegroundColor Black "`t`t###Adding value `"$PropValue`" to Attribute `"$prop`"###"  
           [void]($VM | Set-Annotation -CustomAttribute $Prop -Value $Propvalue)  
       } #Foreach ($Prop in $properties)  
     } #Foreach ($VM in $VMList)  
   } #Process  
   End{  
   } #End  
 }  
Using this script is fairly simple you can copy paste this code in Powershell profile, on how to use powershell profile you can check my another post here., In case if you don,t want to save it in profile, you can copy paste it in text file and rename extension to .ps1. and on the last line of .ps1 file put line Import-VMAnnotation -CSV c:\temp\VMCMDB.csv to execute this function, and execute it in powershell doing dot sourcing file ie: .\script.ps1 (Before executing make sure you have run as administrator powershell and Set-ExecutionPolicy RemoteSigned (or bypass or unrestricted))

This script requires earlier imported annotation CSV file, no modification in csv file required it should be as it is. and execute function with below command.
Import-VMAnnotation -CSV c:\temp\VMCMDB.csv

Once the script is executed you can see results as on the screen. you don't have to even create vm Annotation attribute, this script take care of it.
I can see the all old information on new vCenter under vm annotations and notes.
If you find this article informative please do share the knowledge. 
Other useful articles on importing and exporting VM information

Exporting virtual machine annotation (Attributes) and notes to CSV file - Powercli

Move/Migrate VMs to folder Path on another vCenter - Powercli

Get vCenter VM folder Path from VMs and Templates- Powercli

Importing VM annotation (Attributes) and notes from CSV file into vCenter - Powercli

Import vCenter roles (privileges) - Powercli

Export vcenter roles (privileges)

Monday, January 18, 2016

Exporting virtual machine annotation (Attributes) and notes to CSV file - Powercli

As I wanted to retain all the configuration and Information about VMs from previous vCenter and apply the same information on another vCenter - (Migration is about moving from Windows vCenter 5.5 to vCenter application linux 6.0 based for testing purpose), I was doing some Esxi migration to another vCenter and earlier I had written 2 script to Get Virtual machine folder Path from and VMs and Templates and Move them to the exact same folder hierarchy on another vcenter.
For small projects where there is no CMDB (Configuration Management Database) Tool is not available, you can maintain your poor mans CMDB in vCenter to fill up information about VMs and hosts or any other object, and can be used it to track information, I have implemented this process in office and made it mandatory for colleagues. Whenever VM is created, Annotation and Notes must be filled with the information (ask project team). This way I don't have to look out or ask project team about VM info every time I need. This is good for time begin CMDB tools not exist, or tools in implementation phase, and it helped me lot in the past by maintaining this data.

Back to exporting Annotation and Notes, This is the script I written today, to get the information, My annotation consist, Application Info, Contact No and Email of the team or owner of VM, Environment whether Production, Critical. Maintenance Windows (Very useful one), Project and Sub project, Notes consist any setting or any other useful information about VM. In case if your annotation attributes does match the names I have, it doesn't matter, My script can pull the information in nice CSV view.
Once you export the info to CSV you can check Import-VMAnnotation script to import information into new vCenter.

Importing VM annotation (Attributes) and notes from CSV file into vCenter - Powercli


This is the script:
 function Export-VMAnnotation {  
   <#   
   .SYNOPSIS   
   Export VM information Folderpath, Annotation Notes  
   .DESCRIPTION   
   The function retrives folderPath, Annotation, Notes from vcenter, it can be exported to csv file.  
   .NOTES    
   Author: Kunal Udapi   
   http://kunaludapi.blogspot.com   
   .PARAMETER N/a   
   No Parameters Required   
   .EXAMPLE   
   PS> Export-VMAnnotation -Datacenter DatacenterName   
   .EXAMPLE   
   PS> Export-VMAnnotation -Datacenter DatacenterName | Export-CSV -Path c:\Temp\VMCMDB.csv  
   #>   
   [CmdletBinding()]  
   #####################################    
   ## ## Version: 1    
   ## Tested this script on successfully   
   ## 1) Powershell v4    
   ## 2) Windows 8.1  
   ## 3) vSphere 5.5 (vcenter, esxi)  
   ## 4) powercli 6.0  
   #####################################    
   Param (  
     [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)]   
     [ValidateNotNullOrEmpty()]   
     [Alias("Name")]   
     [string]$DataCenter  
   )  
   Begin {  
     if (-not(Get-PSSnapin vmware.vimautomation.core -ErrorAction SilentlyContinue)) {  
       Add-PSSnapin vmware.vimautomation.core  
     } #if  
     function Get-VMFolderPath {   
      <#   
      .SYNOPSIS   
      Get folder path of Virtual Machines   
      .DESCRIPTION   
      The function retrives complete folder Path from vcenter (Inventory >> Vms and Templates)   
      .NOTES    
      Author: Kunal Udapi   
      http://kunaludapi.blogspot.com   
      .PARAMETER N/a   
      No Parameters Required   
      .EXAMPLE   
      PS> Get-VM vmname | Get-VMFolderPath   
      .EXAMPLE   
      PS> Get-VM | Get-VMFolderPath   
      .EXAMPLE   
      PS> Get-VM | Get-VMFolderPath | Out-File c:\vmfolderPathlistl.txt   
      #>   
      #####################################    
      ## http://kunaludapi.blogspot.com    
      ## Version: 1    
      ## Windows 8.1    
      ## Tested this script on    
      ## 1) Powershell v4    
      ## 2) VMware vSphere PowerCLI 6.0 Release 1 build 2548067    
      ## 3) Vsphere 5.5    
      #####################################    
       Begin {} #Begin   
       Process {   
        foreach ($vm in $Input) {   
         $DataCenter = $vm | Get-Datacenter   
         $DataCenterName = $DataCenter.Name   
         $VMname = $vm.Name   
         $VMParentName = $vm.Folder   
         if ($VMParentName.Name -eq "vm") {   
          $FolderStructure = "{0}\{1}" -f $DataCenterName, $VMname   
          $FolderStructure   
          Continue   
         }#if ($VMParentName.Name -eq "vm")   
         else {   
          $FolderStructure = "{0}\{1}" -f $VMParentName.Name, $VMname   
          $VMParentID = Get-Folder -Id $VMParentName.ParentId   
          do {   
           $ParentFolderName = $VMParentID.Name   
           if ($ParentFolderName -eq "vm") {   
            $FolderStructure = "$DataCenterName\$FolderStructure"   
            $FolderStructure   
            break   
           } #if ($ParentFolderName -eq "vm")   
           $FolderStructure = "$ParentFolderName\$FolderStructure"   
           $VMParentID = Get-Folder -Id $VMParentID.ParentId   
          } #do   
          until ($VMParentName.ParentId -eq $DataCenter.Id) #until   
         } #else ($VMParentName.Name -eq "vm")   
        } #foreach ($vm in $VMList)   
       } #Process   
       End {} #End   
      } #function Get-VMFolderPath    
   } #Begin  
   Process {  
     $VMList = Get-Datacenter $DataCenter | Get-VM  
     foreach ($vm in $VMList) {  
               $Annotation = $vm | Get-Annotation  
       $IPAddress = $vm.extensiondata.guest.ipaddress -Join ", "  
               $FolderPath = $vm | Get-VMFolderPath  
       $InfoObj = New-Object PSObject  
       $InfoObj | Add-Member -MemberType NoteProperty -Name VMNAME -Value $vm.Name  
               $InfoObj | Add-Member -MemberType NoteProperty -Name IPAddress -Value $IPAddress  
       $InfoObj | Add-Member -MemberType NoteProperty -Name PowerState -Value $vm.Powerstate  
       $InfoObj | Add-Member -MemberType NoteProperty -Name FolderPath -Value $FolderPath  
       $InfoObj | Add-Member -MemberType NoteProperty -Name Notes -Value $vm.Notes  
       foreach ($Attr in $Annotation) {  
         $InfoObj | Add-Member -MemberType NoteProperty -Name $($Attr.Name) -Value $Attr.Value  
       }  
               $InfoObj  
     } #foreach $vm  
   } #Process  
   end {}  
 }#function Export-VMAnnotation  
Using this script is fairly simple you can copy paste this code in Powershell profile, on how to use powershell profile you can check my another post here., In case if you don,t want to save it in profile, you can copy paste it in text file and rename extension to .ps1. and on the last line of .ps1 file put line Export-VMAnnotation to execute this function, and execute it in powershell doing dot sourcing file ie: .\script.ps1 (Before executing make sure you have run as administrator powershell and Set-ExecutionPolicy RemoteSigned (or bypass or unrestricted))

Once the function executated as below, You will see results on console.
Export-VMAnnotation -Datacenter DatacenterName
If you want to export information to CSV (excel). You can execute
Export-VMAnnotation -Datacenter DatacenterName | Export-CSV -Path C:\Temp\VMCMDB.csv
It pulls below information additionally, and doesn't require any changes in the original script.
VMName,
IPAddress
PowerState
FolderPath (This is my earlier script I have used to pull information)
VM notes
VM annotation and Attribution.


Although I had written sepearte article for folderpath but I wanted to keep all incormation in same file.I hope this is been informative, Stay tuned for my another script on importing VM notes and annotation in another vCenter.

Other useful information on migration

Exporting virtual machine annotation (Attributes) and notes to CSV file - Powercli

Move/Migrate VMs to folder Path on another vCenter - Powercli

Get vCenter VM folder Path from VMs and Templates- Powercli

Importing VM annotation (Attributes) and notes from CSV file into vCenter - Powercli

Import vCenter roles (privileges) - Powercli

Export vcenter roles (privileges)

Friday, January 15, 2016

Move/Migrate VMs to folder Path on another vCenter - Powercli

This is my second post in the 2016, first post was about Getting VMs folder Path from VMs and Templates vCenter., Which helped me to backup those VMs folder path from VMs and template, but the next task was to move vms to its respective folder.

This is the script I used to migrate VMs to folder path, You can check on how to keep this function in Powershell profile from my earlier post. Also make sure you have already got vms folder path before moving esxi to new vcenter and list is in text file as shown earlier.
 function Move-VMtoFolderPath {  
 <#  
 .SYNOPSIS  
 Move VM to folder path  
 .DESCRIPTION  
 The function retrives complete folder Path from vcenter (Inventory >> Vms and Templates)  
 .NOTES   
 Author: Kunal Udapi  
 http://kunaludapi.blogspot.com  
 .PARAMETER N/a  
 No Parameters Required  
 .EXAMPLE  
  PS> Get-Content -Path c:\temp\VmFolderPathList.txt | Move-VMtoFolderPath  
 #>  
  #####################################    
  ## http://kunaludapi.blogspot.com    
  ## Version: 1    
  ##    
  ## Tested this script on    
  ## 1) Powershell v4    
  ## 2) VMware vSphere PowerCLI 6.0 Release 1 build 2548067    
  ## 3) Vsphere 5.5    
  #####################################    
   Foreach ($FolderPath in $Input) {  
     $list = $FolderPath -split "\\"  
     $VMName = $list[-1]  
     $count = $list.count - 2  
     0..$count | ForEach-Object {  
          $number = $_  
       if ($_ -eq 0 -and $count -gt 2) {  
               $Datacenter = Get-Datacenter $list[0]  
          } #if ($_ -eq 0)  
       elseif ($_ -eq 0 -and $count -eq 0) {  
               $Datacenter = Get-Datacenter $list[$_]  
               #VM already in Datacenter no need to move  
         Continue  
       } #elseif ($_ -eq 0 -and $count -eq 0)  
       elseif ($_ -eq 0 -and $count -eq 1) {  
         $Datacenter = Get-Datacenter $list[$_]  
       } #elseif ($_ -eq 0 -and $count -eq 1)  
       elseif ($_ -eq 0 -and $count -eq 2) {  
         $Datacenter = Get-Datacenter $list[$_]  
       } #elseif ($_ -eq 0 -and $count -eq 2)  
          elseif ($_ -eq 1) {  
               $Folder = $Datacenter | Get-folder $list[$_]  
          } #elseif ($_ -eq 1)  
          else {  
         $Folder = $Folder | Get-Folder $list[$_]  
          } #else  
     } #0..$count | foreach  
     Move-VM -VM $VMName -Destination $Folder  
   } #Foreach ($FolderPath in $VMFolderPathList)  
 }#function Set-FolderPath  

Next is login to new vcenter using powercli and execute. (Make sure you have datacenter, and folder names are same on other vCenter, and created them time ahead, so you dont miss the thing and retain all the folder structure as it is)
Get-Content -Path c:\temp\VmFolderPathList.txt | Move-VMtoFolderPath

Once executed, you will see what vms has been moved.
You can also monitor tasks in vCenter to view what is going on. 
once everything is fine, you will see actual result in VMs and template under Inventory, all the vms moved to its respective folder.

Other Useful blogs

Exporting virtual machine annotation (Attributes) and notes to CSV file - Powercli

Move/Migrate VMs to folder Path on another vCenter - Powercli

Get vCenter VM folder Path from VMs and Templates- Powercli

Importing VM annotation (Attributes) and notes from CSV file into vCenter - Powercli

Import vCenter roles (privileges) - Powercli

Export vcenter roles (privileges)

Get vCenter VM folder Path from VMs and Templates- Powercli

Next blog: Move/Migrate VMs to folder Path on another vCenter - Powercli

Recently I was involved with moving/ migrating ESXi server from one vcenter to another vcenter, (Migration is about moving from Windows vCenter 5.5 to vCenter application linux 6.0 based for testing purpose) Everything was smooth, but I found, I lost my Folders and hierarchy in VMs and Template view in new vCenter. To resolve this issue, one has to note down all my folders path for VMs. and replicate the same setup on new vCenter. and then move those VMs to folders respectively. To automate and to retain the same folder settings I wrote this script. It helps me to backup and save the complete folder path of VM in text file and I can later use it to restore or move VMs to those path accurately.
Below is the code for Getting VMFolderPath
 function Get-VMFolderPath {  
 <#  
 .SYNOPSIS  
 Get folder path of Virtual Machines  
 .DESCRIPTION  
 The function retrives complete folder Path from vcenter (Inventory >> Vms and Templates)  
 .NOTES   
 Author: Kunal Udapi  
 http://kunaludapi.blogspot.com  
 .PARAMETER N/a  
 No Parameters Required  
 .EXAMPLE  
  PS> Get-VM vmname | Get-VMFolderPath  
 .EXAMPLE  
  PS> Get-VM | Get-VMFolderPath  
 .EXAMPLE  
  PS> Get-VM | Get-VMFolderPath | Out-File c:\vmfolderPathlistl.txt  
 #>  
  #####################################    
  ## http://kunaludapi.blogspot.com    
  ## Version: 1    
  ## Windows 8.1   
  ## Tested this script on    
  ## 1) Powershell v4    
  ## 2) VMware vSphere PowerCLI 6.0 Release 1 build 2548067    
  ## 3) Vsphere 5.5    
  #####################################    
   Begin {} #Begin  
   Process {  
     foreach ($vm in $Input) {  
       $DataCenter = $vm | Get-Datacenter  
       $DataCenterName = $DataCenter.Name  
       $VMname = $vm.Name  
       $VMParentName = $vm.Folder  
       if ($VMParentName.Name -eq "vm") {  
         $FolderStructure = "{0}\{1}" -f $DataCenterName, $VMname  
         $FolderStructure  
         Continue  
       }#if ($VMParentName.Name -eq "vm")  
       else {  
         $FolderStructure = "{0}\{1}" -f $VMParentName.Name, $VMname  
         $VMParentID = Get-Folder -Id $VMParentName.ParentId  
         do {  
           $ParentFolderName = $VMParentID.Name  
           if ($ParentFolderName -eq "vm") {  
             $FolderStructure = "$DataCenterName\$FolderStructure"  
             $FolderStructure  
             break  
           } #if ($ParentFolderName -eq "vm")  
           $FolderStructure = "$ParentFolderName\$FolderStructure"  
           $VMParentID = Get-Folder -Id $VMParentID.ParentId  
         } #do  
         until ($VMParentName.ParentId -eq $DataCenter.Id) #until  
       } #else ($VMParentName.Name -eq "vm")  
     } #foreach ($vm in $VMList)  
   } #Process  
   End {} #End  
 } #function Get-VMFolderPath    
You can keep this code in your powershell profile. I have given steps editing Profile in this postOnce you setup profile, login into vcenter using powercli, and run below command.

Get-VM | Get-VMFolderPath | Out-File c:\temp\VmFolderPathList.txt
Above is the screenshot of notepad results, if you are not specifying out-file and showing results on console below is the screenshot.
My next blog will be about how to restore or move Vms to their respective folders on another vCenter.

Move/Migrate VMs to folder Path on another vCenter - Powercli


Other Useful blogs

Exporting virtual machine annotation (Attributes) and notes to CSV file - Powercli

Move/Migrate VMs to folder Path on another vCenter - Powercli

Get vCenter VM folder Path from VMs and Templates- Powercli

Importing VM annotation (Attributes) and notes from CSV file into vCenter - Powercli

Import vCenter roles (privileges) - Powercli

Export vcenter roles (privileges)