umms
Enthusiast
Enthusiast

Move VMs to Folders

Jump to solution

I have exported into CSV file the VMs and the Folder Paths in format:

Name                    Path

Not having much luck importing these to move the VMs to the folder structure (which is already in place). Can anyone give me some suggestions of Code to try? Thanks.

0 Kudos
55 Replies
umms
Enthusiast
Enthusiast
VMName                                FolderName
------                                ----------
UCSSMgt08.UMASSHS.net - off           \UMASSHS\Discovered virtual machine\UCSSMgt08.UMASSHS.net - off
UCSSMgt07.UMASSHS.net                 \UMASSHS\Discovered virtual machine\UCSSMgt07.UMASSHS.net
ucssvisionmsp                         \UMASSHS\Discovered virtual machine\ucssvisionmsp
ucssvisionmsm                         \UMASSHS\Discovered virtual machine\ucssvisionmsm
UCSS-N1K-AS01-1                       \UMASSHS\Discovered virtual machine\UCSS-N1K-AS01-1
UCSSMgt02.UMASSHS.net                 \UMASSHS\Discovered virtual machine\UCSSMgt02.UMASSHS.net
ucsshaprox01                          \UMASSHS\Discovered virtual machine\ucsshaprox01
zenoss-ucspm                          \UMASSHS\Discovered virtual machine\zenoss-ucspm
ucssproxy01a                          \UMASSHS\Discovered virtual machine\ucssproxy01a
ucssvnxplugin                         \UMASSHS\Discovered virtual machine\ucssvnxplugin
ucssvisioncore                        \UMASSHS\Discovered virtual machine\ucssvisioncore
UCSSMgt05.UMASSHS.net                 \UMASSHS\Discovered virtual machine\UCSSMgt05.UMASSHS.net
0 Kudos
LucD
Leadership
Leadership

Your column names in the CSV do not correspond with the properties that are used in the script.

Change the last lines to

Import-Csv "c:\csv-files\04-$($datacenter)-vms-with-FolderPath.csv" |

ForEach-Object -Process {

    Move-VM -VM $_.VMName -InventoryLocation (Get-FolderByPath -Path ($_.FolderName.TrimStart('\')))

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
umms
Enthusiast
Enthusiast

PS C:\temp> .\move_folders_vms.ps1
Please enter name or IP address of the vCenter: umwadco1vc.umasshs.net
Please enter name of the Datacenter: UMASSHS

Name                           Port  User
----                           ----  ----
umwadco1vc.umasshs.net         443   VSPHERE.LOCAL\Administrator
You cannot call a method on a null-valued expression.
At C:\temp\move_folders_vms.ps1:64 char:5
+     Move-VM -VM $_.VMName -InventoryLocation (Get-FolderByPath -Path  ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

You cannot call a method on a null-valued expression.
At C:\temp\move_folders_vms.ps1:64 char:5
+     Move-VM -VM $_.VMName -InventoryLocation (Get-FolderByPath -Path  ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

0 Kudos
LucD
Leadership
Leadership

Are you sure the FolderPath values in the CSV are correct?

Try one or more to check if the Get-FolderByPath function can find the Folder.

$folderPath = ' \UMASSHS\Discovered virtual machine\UCSSMgt07.UMASSHS.net'

Get-FolderByPath -Path $FolderPath.TrimStart('\')


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
umms
Enthusiast
Enthusiast

Yes, I am pretty sure they are correct as I am doing it manually by hand now! ran that command (changed the server) and got this:

PS C:\temp> $folderPath = '\UMASSHS\Discovered virtual machine\cyberserver'
PS C:\temp> Get-FolderByPath -Path $FolderPath.TrimStart('\')
Get-FolderByPath : The term 'Get-FolderByPath' is not recognized as the name of a cmdlet, function, script file, or
operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try
again.
At line:1 char:1
+ Get-FolderByPath -Path $FolderPath.TrimStart('\')
+ ~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Get-FolderByPath:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

0 Kudos
LucD
Leadership
Leadership

Ok, you need to dot-source the function of course.

Place the function in a .ps1 file (for example GetFolderByPath.ps1) and then dot-source (yes there is a blank between the two dots) that file.

. .\GetFolderByPath.ps1

Your PS session should now 'know' the function.

You can check by doing

Get-Command -Name Get-FolderByPath


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
umms
Enthusiast
Enthusiast
Sorry I am pretty new to this. What "function" am I putting in a ps1 file? This? - Get-FolderByPath -Path $FolderPath.TrimStart('\') or the whole thing you sent?
0 Kudos
LucD
Leadership
Leadership

I attached the file with the function.
Save the file in the folder where you are located (looks like you are in C:\Temp from your screenshots)

Then do the dot-sourcing

. .\GetFolderByPath.ps1

Check if the function is now known

Get-Command -Name Get-FolderByPath


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
LucD
Leadership
Leadership

I attach the same file with the .txt extension (some AV apps seem to have an issue with the .ps1 extension).
Rename to a .ps1 file


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
umms
Enthusiast
Enthusiast
PS C:\temp> . .\GetFolderByPath.ps1
. : File C:\temp\GetFolderByPath.ps1 cannot be loaded. The file C:\temp\GetFolderByPath.ps1 is not digitally signed.
You cannot run this script on the current system. For more information about running scripts and setting execution
policy, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
At line:1 char:3
+ . .\GetFolderByPath.ps1
+   ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : SecurityError: (:) [], PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
0 Kudos
umms
Enthusiast
Enthusiast

Ok, I fixed the digital signature thing. Now when I run these commands I get:

PS C:\temp> $folderPath = '\UMASSHS\Discovered virtual machine\cyberserver'
PS C:\temp> Get-FolderByPath -Path $FolderPath.TrimStart('\')
PS C:\temp>

 

PS C:\temp> Get-Command -Name Get-FolderByPath

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Get-FolderByPath


PS C:\temp>

0 Kudos
LucD
Leadership
Leadership

Ok, now run the Get-FolderByPath test again for a single folder from the CSV.

$folderPath = ' \UMASSHS\Discovered virtual machine\UCSSMgt07.UMASSHS.net'

Get-FolderByPath -Path $FolderPath.TrimStart('\')

And to make it complete, for the full CSV

$destVI = Read-Host "Please enter name or IP address of the vCenter"

$creds = Get-Credential -Message 'Enter credentials for $destVI'

$datacenter = Read-Host 'Please enter name of the Datacenter'

Connect-VIServer -server $destVI -Credential $creds


Import-Csv "c:\csv-files\04-$($datacenter)-vms-with-FolderPath.csv" |

ForEach-Object -Process {

    Write-Host -"Folder $($_.FolderName)"

    Get-FolderByPath -Path $_.FolderName.TrimStart('\')

}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
umms
Enthusiast
Enthusiast

Still getting this unfortunately.

You cannot call a method on a null-valued expression.
At C:\temp\test_move2.ps1:64 char:5
+     Move-VM -VM $_.VMName -InventoryLocation (Get-FolderByPath -Path  ...
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : InvokeMethodOnNull

0 Kudos
LucD
Leadership
Leadership

That is not what I suggested as the next step


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
umms
Enthusiast
Enthusiast

Sorry I posted that before I read the next stop. So here is out put from this:

PS C:\temp> $folderPath = ' \UMASSHS\Discovered virtual machine\UCSSMgt07.UMASSHS.net '
PS C:\temp> Get-FolderByPath -Path $FolderPath.TrimStart('\')
PS C:\temp>

It doesnt do anything? Not sure if that is what we are looking for?

0 Kudos
LucD
Leadership
Leadership

Not really, it should return a Folder object.
And that is why you are getting the errors on the Move-VM.

Ok, is in \UMASSHS\Discovered virtual machine\UCSSMgt07.UMASSHS.net  the UMASSHS the datacenter name?

Check with

Get-Datacenter -Name UMASSHS

The rest of the qualifiers in the string should then be Folders. You can test the complete path like this

Get-Datacenter -Name UMASSHS | Get-Folder -Name 'Discovered virtual machine' |

Get-Folder -Name 'UCSSMgt07.UMASSHS.net'


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
umms
Enthusiast
Enthusiast
Should - UCSSMgt07.UMASSHS.net by the Folder name or VMname? Attached is output since the forum wont let me post in here
0 Kudos
LucD
Leadership
Leadership

You seem to have a blank at the start of Discovered virtual machine


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
umms
Enthusiast
Enthusiast
PS C:\temp> Get-Datacenter -Name UMASSHS | Get-Folder -Name 'Discovered virtual machine' |
>> Get-Folder -Name 'Management'
Get-Folder : 2/16/2020 3:18:41 PM       Get-Folder              Folder with name 'Management' was not found using the specified
filter(s).
At line:2 char:1
+ Get-Folder -Name 'Management'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (:) [Get-Folder], VimException
    + FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetFol
   der
0 Kudos
umms
Enthusiast
Enthusiast

So I am wondering why I can't even query a Folder. 

PS C:\temp> Get-Folder -Name 'Discover virtual machine'
Get-Folder : 2/16/2020 3:31:03 PM       Get-Folder              Folder with name 'Discover virtual machine' was not found using the
specified filter(s).
At line:1 char:1
+ Get-Folder -Name 'Discover virtual machine'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (:) [Get-Folder], VimException
    + FullyQualifiedErrorId : Core_OutputHelper_WriteNotFoundError,VMware.VimAutomation.ViCore.Cmdlets.Commands.GetFol
   der

0 Kudos