azurepowershellsplit

PowerShell Split String After X Segments


Trying to get a substring out of a larger string from an Azure Subnet. The vnet resource id is identical to the subnet resource id minus the last 2 segments. User inputs the resource id of the subnet, and I want to get the resource id of the vnet out of it. The vnets could have different naming conventions, so the length of the "substring" won't always be the same, but the vnet id will always be the subnet id minus the last 2 segments.

For example, is there an easy way to get string2 from string 1, where the length of string 2 might vary. Let's say string1 is:

abc/def/ghi/jkl/mno

and I want to get the first 3 segments of this string so that string2 will be:

abc/def/ghi

Is there an easy operation that can be performed that will cut off the last 2 segments despite the length of, in this case, the first three? To clarify with different lengths, if the user then puts in a different string1:

abcdef/ghi/jklmn/opqr/stuvwx

string2 should be:

abcdef/ghi/jklmn

I have tried using .split but it only gives me the text after the delimiter and .substring I believe needs a start and end index, which again might vary.


Solution

  • tl;dr

    An example subnet id in Azure might be something like:

    /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx/resourceGroups/rg-myrg/providers/Microsoft.Network/virtualNetworks/my-vnet/subnets/my-subnet
    

    To get the virtual network (vnet) id you want to remove the last 2 segments:

    $subnet_id = "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx/resourceGroups/rg-myrg/providers/Microsoft.Network/virtualNetworks/my-vnet/subnets/my-subnet"
    
    $parts = $subnet_id.Split("/")
    $vnet_id = $parts[0..($parts.Length-3)] -join "/"
    
    $vnet_id
    # /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx/resourceGroups/rg-myrg/providers/Microsoft.Network/virtualNetworks/my-vnet
    

    Details

    The first step is to split the subnet id into an array of parts:

    PS> $subnet_id.Split("/")
    
    subscriptions
    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx
    resourceGroups
    rg-myrg
    providers
    Microsoft.Network
    virtualNetworks
    my-vnet
    subnets
    my-subnet
    

    Note the first item is an empty string because the subnet id starts with a separator.

    It then uses the Range operator to generate an array of integers from zero to "the number of parts in the array minus 3":

    PS> 0..($parts.Length-3)
    
    # 0
    # 1
    # 2
    # 3
    # 4
    # 5
    # 6
    # 7
    # 8
    

    And uses array slicing to extract the items at each of those indices

    PS> $parts[0..($parts.Length-3)]
    
    subscriptions
    xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx
    resourceGroups
    rg-myrg
    providers
    Microsoft.Network
    virtualNetworks
    my-vnet 
    

    (Note the first item in the result is still an empty string)

    It then finally joins those values into a single string with the -join operator:

    PS> $parts[0..($parts.Length-3)] -join "/"
    
    /subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxx/resourceGroups/rg-myrg/providers/Microsoft.Network/virtualNetworks/my-vnet
    

    which gives your vnet id.