Nathan Heaivilin
Nathan Heaivilin

Reputation: 73

PowerShell DSC Conditional Statement issues

Working with PowerShell DSC and having an issue with conditional statements inside the Configuration file. The code is below. I get the following error:

VERBOSE: [AT20BLDTESTDB01]: LCM:  [ Start  Resource ]  [[Disk]diskAdd_T]
VERBOSE: [AT20BLDTESTDB01]: LCM:  [ Start  Test     ]  [[Disk]diskAdd_T]
VERBOSE: [AT20BLDTESTDB01]: LCM:  [ End    Test     ]  [[Disk]diskAdd_T]  in 0.0470 seconds.
PowerShell DSC resource DSC_Disk  failed to execute Test-TargetResource functionality with error message: Cannot bind argument to parameter 'DiskId' because it is an empty string.
    + CategoryInfo          : InvalidOperation: (:) [], CimException
    + FullyQualifiedErrorId : ProviderOperationExecutionFailure
    + PSComputerName        : AT20BLDTESTDB01

The error I'm getting is that the $Disk.UniqueID is null. yet, when I run the query on the machine directly, I get 4 results returned. So, I'm not sure what is going on and could some assistance figuring this out.

Configuration InstallSQLServer {
     param (
          [Parameter(Mandatory)]
          [string[]]$TargetServer
     )
     Import-DscResource -ModuleName PSDesiredStateConfiguration
     Import-DscResource -ModuleName StorageDsc

     $SQLDriveLetters = @{}
     $SQLDriveLetters.Add('E','SQL DATA')
     $SQLDriveLetters.Add('L','SQL LOGS')
     $SQLDriveLetters.Add('T','SQL TEMPDB')
     $SQLDriveLetters.Add('S','SQL SYSTEM')

     node $AllNodes.NodeName {
          foreach ($disk in ((get-disk).OperationalStatus -ieq 'Offline'))
          {
               if ($SQLDriveLetters.Contains('E')) {$DriveLetter = 'E'}
               if ($SQLDriveLetters.Contains('L')) {$DriveLetter = 'L'}
               if ($SQLDriveLetters.Contains('S')) {$DriveLetter = 'S'}
               if ($SQLDriveLetters.Contains('T')) {$DriveLetter = 'T'}
               
               $DiskID = $disk.UniqueId  
               disk "diskAdd_$DriveLetter"
                   {
                    DiskIDType = "UniqueID"
                    DiskId = "$DiskID"  #"$($Disk.UniqueId)"
                    DriveLetter = "$DriveLetter"
                    FSFormat = 'NTFS'
                    AllocationUnitSize = 64KB
                    FSLabel = $SQLDriveLetters[$DriveLetter]
                   }
               $SQLDriveLetters.Remove($DriveLetter)
          }
     } 
}

Upvotes: 1

Views: 137

Answers (2)

Nathan Heaivilin
Nathan Heaivilin

Reputation: 73

I figured out the issue. I'm creating MOF file on the local system and then pushing that to the remote server. I believed that the GET-DISK would run on the remote system as it's in the NODE section of the CONFIGURATION meta data, but that isn't what was occurring. It was pulling the local disks to use for creating the MOF file.

I fixed this by running GET-DISK -CIMSession $Session, and then passing the object into the Configuration file as a parameter, looping through as shown above.

Appreciate the note on the filtering behavior mklment0.

Upvotes: 1

mklement0
mklement0

Reputation: 439842

(get-disk).OperationalStatus -ieq 'Offline'

  • On a general note: If there's only one disk, this test will return either $true or $false (If you wanted to unconditionally ensure filtering behavior, you'd have to use @((get-disk).OperationalStatus) -ieq 'Offline', but that doesn't make much sense here.)

  • The specific problem is that this expression doesn't return the disks of interest, but either a Boolean (see above) or an array of 'Offline' values.

Presumably, you want the following (disclaimer: I'm not familiar with DSC):

# ...
foreach ($disk in ((get-disk).Where({ $_.OperationalStatus -ieq 'Offline' }))
# ...

Upvotes: 1

Related Questions