locked
Create mountpoint script overwriting partitions RRS feed

  • Question

  • Hi All.

    I have been able to put together the script below, it creates mount points from a single disk at the moment, instead of hardcoding things, I decided to put it within a loop, the issue i am finding is that some of the partitions are overwritten as i do not know the last partition number programatically, this is needed so as to increment the partition number by one for the next mount point.

    $all_drives = (Get-Volume).DriveLetter
    if ($all_drives -notcontains 'D')
    {
    	$root_drive = "D"
    	New-Partition  -DiskNumber 1 -DriveLetter $root_drive -Size 40GB
    	Format-Volume -DriveLetter $root_drive  -FileSystem NTFS -NewFileSystemLabel “SQL D” -Confirm:$false -Force
    
    }
    
    
    
    
    $root_drive = "E"
    New-Partition  -DiskNumber 1 -DriveLetter $root_drive -Size 1GB
    $root_drive = "E"
    Format-Volume -DriveLetter $root_drive  -FileSystem NTFS -NewFileSystemLabel “Root E” -Confirm:$false -Force
    
    
    $data_disk = 15GB
    $log_disk = 10GB
    $tempdb_disk = 10GB
    $sys_disk = 10GB
    $dump_disk = 10GB
    
    $all_drives = (Get-Volume).DriveLetter
    if ($all_drives -contains 'E')
    {
    
    
    	$mounts = @("DATA","LOG","SYS","TEMPDB","BACKUP")
    
    	foreach ($mountpoints in $mounts)
    	{
    
    
    			$noofdrives = 1
    			$root_drive = "E:"
                $disk_no = 1
    
    			$partition = 1
    			For ($i=1; $i -le $noofdrives ; $i++) 
    			{
    			
    				switch ($mountpoints)
    				{
    					"DATA" {$disk_allocation = $data_disk; break}
    					"LOG" {$disk_allocation = $log_disk; break}
    					"SYS" {$disk_allocation = $sys_disk; break}
    					"TEMPDB" {$disk_allocation = $tempdb_disk; break}
    					"BACKUP" {$disk_allocation = $dump_disk; break}
    					default {10; break}
    				}
    
    			  $partition = $mounts.IndexOf($mountpoints) + 3
    
    			   write-host "Disk no is $i and partition number is $partition and capacity is mount point $mountpoints and disk = $disk_allocation.ToString()"
    
    					   $datadirtype = $root_drive + "\$mountpoints"+ $i.ToString('00')
    					   New-Item $datadirtype –ItemType Directory
    					   New-Partition –DiskNumber $disk_no -Size $disk_allocation
    					   Add-PartitionAccessPath -DiskNumber $i -PartitionNumber 2 –AccessPath $datadirtype
    					   Get-Partition –Disknumber $disk_no –PartitionNumber $partition | Format-Volume –FileSystem NTFS –NewFileSystemLabel $datadirtype -AllocationUnitSize 65536 –Confirm:$false
    			
    
    
    			}
    
    	}
    
    }
    
    
    What appears to be happening is that E: is then overwritten as E:\DATA01 with 1GB, it should be E: with 1GB and E:\DATA01 with 15GB.

    Tuesday, July 23, 2019 8:07 PM

All replies

  • There is a lot of logic that is missing or wrong.

    The first obvious thing is that you need to check if the drive is empty and be sure that bot drive letters are not in use.

    This would be the best way to do this:

    function Create-Storage{ Param( [Parameter(Mandatory)] $DiskNumber ) if(Get-Volume D,E -ErrorAction 0){ Write-Host 'A drive letter already in used' }else{ $ErrorActionPreference = 'Stop' Try{ # create first partitions New-Partition -DriveLetter D -DiskNumber $DiskNumber -Size 40GB Format-Volume -DriveLetter D -FileSystem NTFS -NewFileSystemLabel 'SQL D' -Confirm:$false -Force New-Partition -DriveLetter E -DiskNumber $DiskNumber -Size 1GB Format-Volume -DriveLetter E -FileSystem NTFS -NewFileSystemLabel 'Root E' -Confirm:$false -Force # create linked partitions $partitions = @{ DATA = 15GB LOG = 10GB SYS = 10GB TEMPDB = 10GB BACKUP = 10GB } $partno = 2 foreach($key in $partitions.Keys){ $partno++                 $mp = "E:\$key"

                    write-host "Disk no is $DiskNumber and partition number is $partno and capacity is $($partitions[$key]) mount point $mp and disk is $DiskNumber"
    New-Item -Name $mp -ItemType Directory New-Partition -DiskNumber $DiskNumber -Size $partitions[$key] | Format-Volume -FileSystem NTFS -NewFileSystemLabel $key -AllocationUnitSize 65536 -Confirm:$false Add-PartitionAccessPath -DiskNumber $DiskNumber -PartitionNumber $partno -AccessPath $mp } } Catch{ Throw $_ } } } Create-Storage -DiskNumber 1



    \_(ツ)_/





    Tuesday, July 23, 2019 10:22 PM
  • Thanks for this, I will test it.
    Tuesday, July 23, 2019 10:27 PM
  • Please note that what you are doing will create storage with extremely poor performance because the heads will have to move a greater distance to change between partitions.  SQL database storage should be allocated on separate physical drives or performance will degrade rapidly with this plan.  JUst place all folders on one partition and let the OS optimize access.


    \_(ツ)_/

    Tuesday, July 23, 2019 10:33 PM
  • Thanks for this, I will test it.

    It should work but I don't have a spare drive to test with so you will have to check the errors carefully.

    I edited the code so be sure you have the last version after my edit.


    \_(ツ)_/

    Tuesday, July 23, 2019 10:35 PM
  • Here is amore concise approach that eliminates the need to calculate the partition number and eliminates calculated variables.  This is a "best practices" approach to PowerShell scripting.

    function Create-Storage{
        Param(
            [Parameter(Mandatory)]
            $DiskNumber = 1
        )
        
        $ErrorActionPreference = 'Stop'
        $ConfirmPreference = 'Low'
        
        Try {
            
            $partitions = @{
                DATA   = 15GB
                LOG    = 10GB
                SYS    = 10GB
                TEMPDB = 10GB
                BACKUP = 10GB
            }
            
            # check for free space
            $disk = Get-Disk -Number $DiskNumber 
            $totalrequest = ($partitions.GetEnumerator() | Measure-Object value -sum).Sum
            if((($disk.Size - $disk.AllocatedSize) - ($totalRequest + 41Gb)) -le 0){
                Throw 'Not enough space'
                return
            }
            
            # check drive letter availability
            if(Get-Volume D,E -ErrorAction 0){
                Throw 'A drive letter already in use'
                return
            }
            
            # create first partitions
            $disk | New-Partition -DriveLetter D -Size 40GB
            Format-Volume -DriveLetter D -FileSystem NTFS -NewFileSystemLabel 'SQL D'
            $disk | New-Partition -DriveLetter E -DiskNumber $DiskNumber -Size 1GB
            Format-Volume -DriveLetter E -FileSystem NTFS -NewFileSystemLabel 'Root E'
            
            # create linked partitions
            foreach($key in $partitions.Keys){
                write-host "Disk no is $DiskNumber and partition number is $partno and capacity is $($partitions[$key]) mount point $mp and disk is $DiskNumber"
                
                $disk | New-Partition -Size $partitions[$key] | 
                    Format-Volume -FileSystem NTFS -NewFileSystemLabel $key -AllocationUnitSize 65536
                New-Item -Path E:\$key -ItemType Directory |
                    Add-PartitionAccessPath -AccessPath $link
            }
        }
        Catch{
            Throw $_
        }
    }
    
    
    Create-Storage -DiskNumber 1
    
    


    \_(ツ)_/







    Tuesday, July 23, 2019 11:56 PM
  • Hi,

    Was your issue resolved?

    If you resolved it using our solution, please "mark it as answer" to help other community members find the helpful reply quickly.

    If you resolve it using your own solution, please share your experience and solution here. It will be very beneficial for other community members who have similar questions.

    If no, please reply and tell us the current situation in order to provide further help.

    Best Regards,

    Lee


    Just do it.

    Wednesday, July 31, 2019 6:57 AM
  • Here is amore concise approach that eliminates the need to calculate the partition number and eliminates calculated variables.  This is a "best practices" approach to PowerShell scripting.

    function Create-Storage{
        Param(
            [Parameter(Mandatory)]
            $DiskNumber = 1
        )
        
        $ErrorActionPreference = 'Stop'
        $ConfirmPreference = 'Low'
        
        Try {
            
            $partitions = @{
                DATA   = 15GB
                LOG    = 10GB
                SYS    = 10GB
                TEMPDB = 10GB
                BACKUP = 10GB
            }
            
            # check for free space
            $disk = Get-Disk -Number $DiskNumber 
            $totalrequest = ($partitions.GetEnumerator() | Measure-Object value -sum).Sum
            if((($disk.Size - $disk.AllocatedSize) - ($totalRequest + 41Gb)) -le 0){
                Throw 'Not enough space'
                return
            }
            
            # check drive letter availability
            if(Get-Volume D,E -ErrorAction 0){
                Throw 'A drive letter already in use'
                return
            }
            
            # create first partitions
            $disk | New-Partition -DriveLetter D -Size 40GB
            Format-Volume -DriveLetter D -FileSystem NTFS -NewFileSystemLabel 'SQL D'
            $disk | New-Partition -DriveLetter E -DiskNumber $DiskNumber -Size 1GB
            Format-Volume -DriveLetter E -FileSystem NTFS -NewFileSystemLabel 'Root E'
            
            # create linked partitions
            foreach($key in $partitions.Keys){
                write-host "Disk no is $DiskNumber and partition number is $partno and capacity is $($partitions[$key]) mount point $mp and disk is $DiskNumber"
                
                $disk | New-Partition -Size $partitions[$key] | 
                    Format-Volume -FileSystem NTFS -NewFileSystemLabel $key -AllocationUnitSize 65536
                New-Item -Path E:\$key -ItemType Directory |
                    Add-PartitionAccessPath -AccessPath $link
            }
        }
        Catch{
            Throw $_
        }
    }
    
    
    Create-Storage -DiskNumber 1
    


    \_(ツ)_/







    I tried to run the script, and got the error below.


    New-Partition : The input object cannot be bound to any parameters for the command either because the command does not
    ake pipeline input or the input and its properties do not match any of the parameters that take pipeline input.
    t line:38 char:17
     ...     $disk | New-Partition -DriveLetter E -DiskNumber $DiskNumber -Siz ...
                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
       + CategoryInfo          : InvalidArgument: (MSFT_Disk (Obje...osoft/Windo...):PSObject) [New-Partition], Parameter
      BindingException
       + FullyQualifiedErrorId : InputObjectNotBound,New-Partition
    

    Thursday, December 12, 2019 4:24 PM