4

I am trying to create a PowerShell script that creates folders (nested and multiple). I managed to get the nested folders to work, and I am pretty new to this, but I cant seem to get the multiple folders to work. I basically want to make a string array with each item being a user inputted string. I tried everything but it just doesn't seem to work.

Here's my code

echo "Folder Creator for FS2019 by Skaytacium, enter the values for unlimited nested folders! Remember though, 260 characters is the max nesting limit!"

$count = Read-Host -Prompt 'How many folders? Value'
$count = [int16]$count

$sub = Read-Host -Prompt 'Do you wanna nest? 2/1'

$namestring = "./"
$storay

[string]$array = "0", "0", "0"

$arac = 0
$arac = [int16]$arac


if ($sub -eq "2") {
    echo "The specified folders will be nested"

    while ($count -gt 0) {

        $namestring = $namestring + (Read-Host -Prompt 'Name') + "/"
        $count--
        echo $namestring

        if ($count -eq 0) {
            md $namestring
        }
    }
}

elseif ($sub -eq "1") {
    echo "The specified folders will be consecutive (in the same dir)"

    while ($count -gt 0){
        $storay = Read-Host "Name"
        $array[1] = @("please help")
        echo $array
        $arac++
        $count--
    }
}

Pause
ggorlen
  • 44,755
  • 7
  • 76
  • 106
Skaytacium
  • 63
  • 1
  • 7

1 Answers1

0

Replace:

[string] $array = "0", "0", "0"  # !! creates *single* string

with:

[string[]] $array = "0", "0", "0"  # creates *array* of strings

In your original command, the [string] type constraint to the left of the variable caused the input array (which is implicitly of type [object[]]) to be converted to a single string ([string]) with contents 0 0 0 (PowerShell stringifies arrays by concatenating their elements with separator $OFS, which defaults to a space.)
By contrast, [string[]] results in an array, whose elements are string-typed.

A [...]-enclosed literal in PowerShell refers to a .NET type. It is called a type literal.

  • If you place such a type literal to the left of variable assignment, you type-constrain that variable, meaning that it can only store values that are instances of that type, and that it automatically tries to convert instances of other types to that type, if possible; see this answer for more information about type constraints.

  • You can also use a type literal to cast expressions to that type (as your code does in statement $arac = [int16] $arac), which also means converting the operand to that type, as a one-time operation.

In type literal [string[]], the [] after the type name, string, specifies an array of elements of that type; except for the enclosing [...], this notation is the same as the one used by the .NET Type.GetType() method; see this answer for more information.

Note that PowerShell's type conversions are much more flexible than C#'s for instance; they are augmented by built-in conversion rules and attempts to automatically use appropriate constructors and static .Parse() methods.


Note that you don't strictly need the type constraint [string[]], except if you want to make sure that assigning to elements of this array later automatically performs to-string conversion.

# OK, but creates [object[]] array that now happens to contain [string]
# instances, but the type of the elements isn't locked in.
$array = "0", "0", "0"

As for the specific error message you saw:

Because $array was just a single [string] in your code, indexing with, say, [0] indexes in the string's character array.

Technically, this works for getting characters from the array, but you cannot set them:

# GET the 1st character from the string stored in $var
PS> $var = 'foo'; $var[0]
f     # 1st character in the string

# !! You CANNOT SET characters that way
PS> $var[0] = 'F'
InvalidOperation: Unable to index into an object of type "System.String".
mklement0
  • 382,024
  • 64
  • 607
  • 775