VMware Cloud Community
BrianGordon84
Contributor
Contributor

Auto hd creation, pagefile creation

I've been writing a script to add a new harddrive to a vm, initialize it, format it, assign it a drive letter and then assign a pagefile to it. I have borrowed certain parts of the script from others online. I've got several hundred vm's to use this script on. I'm having problems getting the diskpart to work on a remote system. I know I'm missing a couple of things here. I've been racking my head on this for a few days. Here is the script, any help would be appreciated.

#Add Pagefile Drives to Servers

$Servers = (Get-Content servers.txt)

$datastore = "nosnap_dev01"

$vms = Get-VM $Servers

foreach

($vm in $vms){

$System = GWMI Win32_ComputerSystem -ComputerName $vm.Name -EnableAllPrivileges

if($System.AutomaticManagedPagefile -eq $True){

$System.AutomaticManagedPagefile = $False

$System.Put()}

$pgfsize = 0

$kb = 0

$kbsize = 0

$pgfsize = ($vm.MemoryMB * 1.5) + 2048

$kb = $pgfsize * 1024

$pgf_initial_maximum = ($vm.MemoryMB * 1.5)

$vm | New-HardDisk -CapacityKB $kb -StorageFormat Thin -DataStore $datastore | Out-Null

Write-Host "Pagefile minimum and maximum size is" $pgf_initial_maximum

$drives = gwmi Win32_diskdrive -ComputerName $vm.Name | Where {$_.Partitions -eq "0"}

$scriptdisk = $Null

$script = $Null

$drivenumber = $drives.DeviceID -replace '[\\\\\.\\physicaldrive]',''

Write-Host $drivenumber

$script = @"

select disk $drivenumber

attributes disk clear readonly noerr

create partition primary noerr

format quick

exit

"@

 

$drivenumber = $Null

$scriptdisk += $script + "`n"

Invoke-Command -ComputerName $vm.Name -ScriptBlock {$scriptdisk | diskpart}

Write-Host "Harddrive successfully added and formatted"

$volume = gwmi Win32_Volume -ComputerName $vm.Name | Where {$_.Name -ilike "*volume*" -and $_.SystemVolume -eq $False -and $_.Label -eq $Null}

$letters = 68..89 | ForEach-Object { ([char]$_)+":" }

$freeletters = $letters | Where-Object {

(

New-Object System.IO.DriveInfo($_)).DriveType -eq 'NoRootDirectory'}

mountvol $freeletters[0] $volume.DeviceID

Write-Host "Drive Letter" $freeletters[0] "added"

$hd_name = gwmi Win32_Volume -ComputerName $vm.Name | Where {$_.DriveLetter -eq $freeletters[0]}

$hd_name.Label = "Pagefile"

$hd_name.Put() | Out-Null

Write-Host $hd_name.Label "Label added"

$pagefile_path = $freeletters[0] + "\pagefile.sys"

Set-WMIInstance -class Win32_PageFileSetting -ComputerName $vm.Name -Arguments @{name=$pagefile_path;InitialSize =$pgf_initial_maximum;MaximumSize =$pgf_initial_maximum} | Out-Null

}

0 Kudos
6 Replies
mattboren
Expert
Expert

What are the output and error(s) that you get when you run this against a machine?

0 Kudos
BrianGordon84
Contributor
Contributor

I get several errors when running this script against a remote host. When I run it against the local host the script sits on, it runs perfectly. I think it's got to do with running diskpart remotely. It errors first on the  first wmi call - probably because I haven't provided any credentials in the script.

Here is the error: Connecting to remote server failed with the following error message : WinRM cannot process the request. The following error occured while using Kerberos authentication: An unknown security error occurred.

Diskpart doesn't actually throw an error but I know it's not running remotely because the harddisk is not initializing, being formatted or assigned a drive letter. Once this fails, the rest of the script is dead in the water.

0 Kudos
mattboren
Expert
Expert

Ok.  To cover bases, does the account that is running the PowerShell script have sufficient rights on the VM for Invoke-Command?  By the way you say that the Get-WmiObject cmdlet fails (likely due to credentials), it sounds like there might be a lack-of-rights involved.

With that same account, can you run a simple command via Invoke-Command on the target VM?  Like, maybe:

Invoke-Command -ComputerName myVM -ScriptBlock {ipconfig.exe}

Another thing to verify:  PSRemoting is enabled on the target VM?  If not, then that would need to be enabled before the Invoke-Command call would work.

And, another option would be to use Invoke-VMScript to initiate a script in the target VM, if you have not already investigated that.

0 Kudos
BrianGordon84
Contributor
Contributor

The account running the script has the privleges, that's not the issue. It looks like PSRemoting is not turned on for the wmi on remote systems. I'll have to do some research on that to see if I can turn it on, on several hundred vm's or if that's not a good idea. So the other issue is getting the diskpart to work on remote systems. A lot of the servers are 2003, they do not have powershell installed and I'm not going to spend the time doing it. I might have to try another route on this, maybe run it through a batch file or find another way to automate diskpart. Any other ideas?

0 Kudos
mattboren
Expert
Expert

Hello, BrianGordon84-

Yes, another idea would be to have the DiskPart commands in a file, copy the file to the target VM, and run diskpart.exe on the target VM with the "/s" parameter to use the given text file with the DiskPart commands in it.

So, it would be like:

## place on the target VM to which to copy txt file
$strDestinationTxtFilespec = "c:\temp\diskPartCmds.txt"
## copy the txt file with the DiskPart cmds from the local machine to the target VM
Copy-VMGuestFile -Source d:\importantStuff\diskPartCmds.txt -Destination $strDestinationTxtFilespec -Force -LocalToGuest -VM $myVM -GuestCredential $credPrivilegedAcct
## run diskpart.exe on the target VM, specifying the given txt file for the commands to run, and then delete the txt file
Invoke-VMScript -ScriptText "diskpart.exe /s $strDestinationTxtFilespec && del $strDestinationTxtFilespec" -VM $myVM -GuestCredential $credPrivilegedAcct -ScriptType bat -Confirm:$false

Your txt file with the DIskPart commands in it is something typical like what you had specified for the "$script" variable in your first post in this thread.

These two cmdlets depend on VMTools to be running properly in the target guest.  Another nice thing about using these two cmdlets is that, since they utilize the guest's VMTools, you do not need direct network connectivity to the guest -- just vCenter access.  That is, too, a possible problem:  if Tools are not running/working properly, neither will the cmdlets.  You could also just copy the file to the guest VM, or even generate it directly on the guest, etc.

Let me know how that does for you.

0 Kudos
AureusStone
Expert
Expert

Firstly, nice script.  I have done the same thing using Orchestrator and VIX, but I had a lot of trouble working out how to get the device ID, so I had to implement a complicated method to do the same thing you do with a line of PowerCLI/WMI. Smiley Happy

As already mentioned you should be running diskpart scripts by calling them with diskpart /s textfile.txt.  Now that has been answered it should work fine.

One issue that remains is the format command for Server 2003 is not available from diskpart.  Instead after the diskpart script is finished run the following command.

echo y | format <DRIVELETTER> /V:DATA /FS:NTFS /Q

0 Kudos