I feel compelled to share a somewhat humorous moment that occurred
yesterday as this thread actually helped me turn a moderately complex piece
of code into something incredibly simple. I apologize in advance for the
lack of brevity....
We have a XenApp 7.6 environment with two separate sites. We use keywords
on the published applications to control which site the application is
launched from via StoreFront. I'm working on a PowerShell script to be used
with Site Recovery Manager that will change the site preference for
specific applications when the back-end systems are migrated to the
alternate site. The trick is that the keywords (Primary or Secondary) are
stored in the description field of the application properties, along with
other potential keywords for various uses. I had to figure out how to parse
keywords so that I could manipulate the single entry I wanted, and then
recompile in the right format and use that to set the new description on
the application.
The field looks like this "Keywords:Primary Auto Stuff Stuff"
When I took my first stab at modifying the desired entry, I figured I had
to split the elements into an array and target the specific keyword. I
first split the elements using the colon, and then split by a blank space
as that's how entries are delimitated in the field.
$Keywords = "Keywords:Primary Auto Stuff Stuff"
$KW1 = $Keywords.Split(":")
$KW2 = $KW1.Split(" ")
At this point I had an array with the following:
Keywords
Primary
Auto
Stuff
Stuff
The next thing I had to figure out was the index number of my desired
entry. I figured easy, I'll just ask our XenApp guys to establish a
standard that the Primary/Secondary keywords would always be first in the
list. Based on that I knew I would always be working with index 1
($KW2[1]). From there it was easy to change the value. I then had to
compile all of the values back into the right format at which point I
realized that I would have to identify how many keywords existed. I ended
up using a rather ugly combination of "IF" statements (e.g. IF ($KW2.count
-eq "5" {build my string with the applicable values}, and repeated that
until the count was 2. As you can imagine, this resulted in a decent number
of lines of code. I knew it was ugly, but it worked.
I shared the code with my colleague and he came up with a somewhat more
elegant solution that involved looping through the values and only changing
the target value. The benefit to his solution was less lines of code, and
it didn't matter the position of my desired value. Looked something like
this:
$Keywords = "Keywords:Primary Auto Stuff Stuff"
$KW1 = $($Keywords.split(":"))[0]
$KW2 = $($Keywords.split(":"))[1]
$KW2 = $KW2.Split(" ")
This process allowed us to segment everything to the left and right of the
colon and manipulate accordingly. We then establish a new variable:
$NewKeyword = $KW1 + ":"
...which repopulates everything to the left of the colon. We then do a
foreach loop for everything within $KW2 and replace the necessary value,
then recompile the new string into the $NewKeyword variable.
So I continued working through the remaining portions of my script when I
came across this thread. Michael's example of the ability to remove values
from an array got me thinking there had to be an even easier way to
manipulate the string I was working with, and of course I landed on the
following:
If ($Keywords -contains "Value") {
$NewKeywords = $Keywords -replace "Value","New Value"
}
Now that I've typed all of this out, it doesn't seem as funny as it once
did, but my colleague and I got a good laugh out of it considering all of
the time we put into the first two attempts. If not for nothing, it further
cements how powerful powershell can be, and how there are multiple ways to
skin the same cat. More importantly, it highlighted the continued benefit I
get from all of the skilled members of this list.
- Sean
On Thu, Oct 19, 2017 at 3:49 PM, Raymond Peng <[email protected]>
wrote:
> Ah – that makes sense. The formatting threw me off as I could not see any
> property via get-member that looked like Destination.
>
> Love the feedback from these posts, thank you Michael and all!!
>
>
>
>
> * Thank you,*
>
>
>
> *Ray*
>
>
>
>
>
> *From:* [email protected] [mailto:listsadmin@lists.
> myitforum.com] *On Behalf Of *Michael B. Smith
> *Sent:* Thursday, October 19, 2017 11:20 AM
> *To:* [email protected]; [email protected]
> *Subject:* [NTSysADM] RE: Powershell array question and formatting
> question
>
>
>
> An array in Windows is of fixed size. If you want something of variable
> size, you use a list or a table. For example, this shows a list which
> contains strings:
>
>
>
>
>
> Now, there is also something called an ArrayList, but let’s not make
> things confusing.
>
>
>
> PowerShell has lots of syntactic sugar around hash tables and ordered hash
> tables. They might be useful to you.
>
>
>
> The formatting question is a little more complicated. That’s because the
> Test-Connection cmdlet is changing the name of the “Destination” column
> behind your back. (The way it does that is complicated, and trust me, you
> don’t really want to know.) To get what you want:
>
>
>
>
>
> But if you are happy with the column being named “Address”, which is the
> true name of the variable:
>
>
>
>
>
> *From:* [email protected] [mailto:listsadmin@lists.
> myitforum.com <[email protected]>] *On Behalf Of *Raymond
> Peng
> *Sent:* Thursday, October 19, 2017 1:34 PM
> *To:* [email protected]; [email protected]
> *Subject:* [NTSysADM] Powershell array question and formatting question
>
>
>
> Hi All,
>
>
>
> Still picking up powershell so please let me know if you see any obvious
> blunders: I see it say the collection is of a fixed size but how do I
> remove?
>
>
>
> I have declared an array with $array=”name1”,”name2”, etc…
>
> I can access each element with $array[0]…
>
>
>
> I can use $array += “name5,”name6” but I can not figure out how to remove
> an element
>
> I have tried the Remove method without any luck as well as -=
>
>
>
> PS C:\WINDOWS\system32> $array.Remove("cxsupportsystems")
>
> Exception calling "Remove" with "1" argument(s): "Collection was of a
> fixed size."
>
> At line:1 char:1
>
> + $array.Remove("cxsupportsystems")
>
> + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>
> + CategoryInfo : NotSpecified: (:) [],
> MethodInvocationException
>
> + FullyQualifiedErrorId : NotSupportedException
>
>
>
>
>
> PS C:\WINDOWS\system32> $array
>
> kcfileserver
>
> wnweb01
>
> pvfile01
>
> corpcxtsgp01
>
> cxsupportsystems
>
>
>
> Lastly – formatting question:
>
>
>
> Is there any way to just crop out the rest and keep the destination /
> IPv4Address info? I tried format-table / select-object but it does not do
> what I want. I’ve tried piping after the test-connection in the scriptblock
> but output is not what I want
>
>
>
>
>
> PS C:\WINDOWS\system32> foreach ($comp in $array){Test-Connection $comp
> -Count 1}
>
>
>
> Source Destination IPV4Address
> IPV6Address Bytes Time(ms)
>
> ------ ----------- -----------
> ----------- ----- --------
>
> L-SM-RPENG1 kcfileserver 172.29.133.130
> 32 62
>
> L-SM-RPENG1 wnweb01 172.29.118.101
> 32 66
>
> L-SM-RPENG1 pvfile01 172.29.171.28
> 32 72
>
> L-SM-RPENG1 corpcxtsgp01 172.29.118.164
> 32 70
>
> L-SM-RPENG1 cxsupportsys... 10.2.1.238
> 32 55
>
>
>
>
>
>
>
>
> * Thank you,*
>
>
>
> *Ray*
>
>
>
>
>