Home > Software design >  How do you make a foreach create multiple variables?
How do you make a foreach create multiple variables?

Time:04-22

I'm trying to make a script that will check a bitlocker encryption percentage and set it as a variable but for each drive.

For example. I run my script that will begin bitlocker encryption on 2 drives. I need a foreach statement that will create a variable foreach drive (2), then I will have an while statement that says while a drive is less than 100 percent, recheck the percentage. Than once it hits 100 percent it will lock the drive.

I don't know how to write code so that I can have it create a while statement for each drive that is detected and has started encrypting.

Sorry if this is confusing I'm new.

Heres my code so far. (DO NOT RUN ON YOUR COMPUTER BECAUSE IT WILL BITLOCK YOUR DRIVES lol, IF YOU WANT TO RUN IT DELETE THE "Enable-Bitlocker" CODE)

#Finds all drives connected to the computer, I'm not sure if this will also detect CDs though, but if it does let me know since they can't be bitlocked
$Drives = Get-BitLockerVolume | Where-Object -Property "MountPoint" | Select-Object -ExpandProperty "MountPoint"

#Encrypts the password so it can't be displayed with a read-host command
$SecureString = ConvertTo-SecureString "test" -AsPlainText -Force

#This will run the bitlocker command and encrypt each drive with the secure password.
foreach ($Drive in $Drives){
    Enable-BitLocker -MountPoint $Drive -EncryptionMethod Aes256 -Password $SecureString -PasswordProtector -SkipHardwareTest
}

#this is supposed to make a new variable for each drive to individually track percentages
foreach ($Drive in $Drives){
    $Percentage = Get-BitLockerVolume | Where-Object -Property "EncryptionPercentage" | Select-Object -ExpandProperty "EncryptionPercentage"
}

#this will continually recheck the percentage until it gets to 100 percent but I need to make it so it will have a while statement for each percentage variable created.
while ($Percentage -LT 100) {
    $Percentage = Get-BitLockerVolume | Where-Object -Property "EncryptionPercentage" | Select-Object -ExpandProperty "EncryptionPercentage"
    sleep -Seconds 10
}

CodePudding user response:

Get-BitLockerVolume only returns valid target volumes, so I wouldn't be too worried about optical drives.

You don't need to create 2 variables to store the percentages - simply use Where-Object to test whether any volume is still under 100, then sleep:

# Fetch any drives that aren't already fully encrypted
$unencryptedVolumes = Get-BitLockerVolume | Where-Object VolumeStatus -ne FullyEncrypted

$SecureString = ConvertTo-SecureString "test" -AsPlainText -Force

# Encrypt each volume with the give password.
$unencryptedVolumes |Enable-BitLocker -EncryptionMethod Aes256 -Password $SecureString -PasswordProtector -SkipHardwareTest

# Keep sleeping until all volumes are fully encrypted
while ($waitingFor = Get-BitLockerVolume | Where-Object VolumeStatus -ne FullyEncrypted) {
    # Print list of in-progress volumes to the screen, sleep
    $waitingFor |Format-Table MountPoint,VolumeStatus,EncryptionPercentage
    Start-Sleep -Seconds 10
}

CodePudding user response:

To answer your question as stated, you want to use set-variable. or get-variable.

This command will store/retrieve variables, and the variables can be named via another variable. This get's tricky, and in order to do math you need to combine them.

for example

Foreach ($number in 1..20) {
    Set-Variable -Name name$number -Value "this is number $number"
    Get-Variable -Name name$number
}

you can also use Remove-Variable or New-Variable but New-Variable is basically superseded by Set-Variable as well as, if a variable exists, New-Variable will spit out an error

in order to do math it get's trickier as you can't just call the variable and add 1

so this is very not effective but something like:

foreach ($number in 1..20) {
    Set-Variable -Name name$number -Value "$((get-variable -name name$number)   1)"
    Get-Variable -Name name$number
}

this could increment it by 1. but now you're calling a ton of stuff to do a simple name1 =1 or name1

you can also do some fancy stuff like

Foreach ($number in 1..20) {
    Set-Variable -Name "name$({0:D2} -f $number)" -Value "this is number $number"
    Get-Variable -Name "name$({0:D2} -f $number)"
}

the more you have, the more you have to code and get (like calling the variable as above is a long string). As the other answer says, usually there's a much simpler option.

  • Related