How do you convert data types in Windows Powershell? - powershell

I'm very new to powershell and am running into walls trying to convert a string to a integer.
If I run the following command: Get-DefaultAudioDeviceVolume it often returns a number that looks something like: 50.05816%, which I have confirmed to be a string. I need to convert this to a whole number integer (50). Obviously I could hard code the integer in my script, but for the purpose of the script I need it to be flexible in it's conversion. The result of the previous test changes and I want to pass along the whole integer further down the line.
Thanks in advance!

If the string contains the % symbol you would need to remove this, then you can use the -as operator to convert to [int]
[string]$vol = "50.05816%"
$vol_int = $vol.Replace('%','') -as [int]
The -as operator is very useful and has many other uses, this article goes through a number of them: https://mcpmag.com/articles/2013/08/13/utilizing-the-as-operator.aspx

Just cast it to integer and replace the "%" with nothing:
[int]$var = (Get-DefaultAudioDeviceVolume).Replace("%","")
Powershell does automatic type casting and starts from the left. So when $var is defined as an integer, it will try to convert the right side to the same type.

Related

PowerShell Digits

Trying to export current temperature from the XML to a text file. The results are are "xx.y" but I only need xx exported to the text file. I've tried several commands but keep striking out. Any ideas?
([xml](Invoke-WebRequest -URI http://w1.weather.gov/xml/current_obs/KSJC.xml).Content).current_observation.temp_f | Out-File c:\temperature.txt
i suspect i am misunderstanding something [this seems alarmingly simple], but here are a few ways to do what it seems you want ... [grin]
$Temperature = '12.3'
$Temperature.Split('.')[0]
[int]$Temperature
[math]::Round([decimal]$Temperature, 0)
the output if each is 12.
the 1st uses the string .Split() method and takes the 1st item in the resulting array
the 2nd uses the [int] type accelerator to coerce the string into an int & rounds it in the process
the 3rd uses the [decimal] type accelerator to coerce the string to a decimal number and the [math]::Round() static method to round the number to 0 decimal places

Add-Content to txt

I'm trying to make a GUI that will print the information from a textbox into a .txt in a way that I will try to explain as well as I can.
$TextBox_UsbName.text = "TestingTesting"
$Button_SetUsbName.Add_Click({ $Value_UsbName = $TextBox_UsbName.text; add-content -path $Value_NewScriptPath -value "$usbname = $Value_UsbName" })
After this is run I was hoping the text file would contain this:
$usbname = "TestingTesting"
I am still new to Powershell as well as coding in general and now I am really stuck I have tried a lot of different ways.
Any ideas and help would be much appreciated.
Edit: My result is
=
In Powershell double quoted string literals, string interpolation takes place each time an unescaped $ appears with a valid identifier characters after it. To introduce a literal $ that should not be parsed as part of an interpolated variable, you should escape it with a backtick, `.
Here is some quick string interpolation help:
How do I expand an expression in a string?
Windows PowerShell will expand a variable or an expression in a string.
Variables look like: $variable
Expressions look like: $(expression)
So, your "$usbname = $Value_UsbName" is interpreted by the engine as value of $usbname variable followded with = enclosed with spaces, and then a value of $Value_UsbName variable.
What you want to add is a literal $usbname substring and the value of $TextBox_UsbName.text expression.
So, either use
"`$usbname = $($TextBox_UsbName.text)"
Or just concatenate values (in a culture independent way):
$usbname + ' = ' + $TextBox_UsbName.text

how to remove # character from national data type in cobol

i am facing issue while converting unicode data into national characters.
When i convert the Unicode data into national using national-of function, some junk character like # is appended after the string.
E.g
Ws-unicode pic X(200)
Ws-national pic N(600)
--let the value in Ws-Unicode is これらの変更は. getting from java end.
move function national-of ( Ws-unicode ,1208 ) to Ws-national.
--after converting value is like これらの変更は #.
i do not want the extra # character added after conversion.
please help me to find out the possible solution, i have tried to replace N'#' with space using inspect clause.
it worked well but failed in some specific scenario like if we have # in input from user end. in that case genuine # also converted to space.
Below is a snippet of code I used to convert EBCDIC to UTF. Before I was capturing string lengths, I was also getting # symbols:
STRING
FUNCTION DISPLAY-OF (
FUNCTION NATIONAL-OF (
WS-EBCDIC-STRING(1:WS-XML-EBCDIC-LENGTH)
WS-EBCDIC-CCSID
)
WS-UTF8-CCSID
)
DELIMITED BY SIZE
INTO WS-UTF8-STRING
WITH POINTER WS-XML-UTF8-LENGTH
END-STRING
SUBTRACT 1 FROM WS-XML-UTF8-LENGTH
What this code does is string the UTF8 representation of the EBCIDIC string into another variable. The WITH POINTER clause will capture the new length of the string + 1 (+ 1 because the pointer is positioned to the next position after the string ended).
Using this method, you should be able to know exactly how long second string is and use that string with the exact length.
That should remove the unwanted #s.
EDIT:
One thing I forgot to mention, in my case, the # signs were actually EBCDIC low values when viewing the actual hex on the mainframe
Use inspect with reverse and stop after first occurence of #

Braces, comma, parameter method call

I'm finding it very hard to google the answer to what the difference is between these two way of executing method calls in powershell:
$member = "1.2.3.4:567" # IPaddress + port for demonstration
$vals1 = $member.Split(":") # typical .NET way of executing String.Split
$vals2 = $member.Split( (,":") ) # something else which ive seen in examples which I dont understand
In the above, both $vals1 and $vals2 appear to have the same result (an array with 2 elements). I would typically use the first way, but in examples (of using both Split and other method calls) I see the second used.
My question is what is the second one doing which is different, and is there any advantages to using it which I may not understand?
Edit: Please don't focus on the Split method - I'm not asking about overloads of Split!
The comma operator used as a unary is what you are seeing. It is a shorthand way to create an array. PowerShell will unroll array in pipelines which is usually desired and standard behavior. Where I see this commonly used is to mitigate that feature of PowerShell
What you would then do in some cases though you do not want PowerShell to unroll the complete array is through the comma unary operator in front of that array. Consider the difference in outputs
Using regular array notation
$array = 1,2,3
$array.Count
$array | ForEach-Object{$_.GetType().FullName}
3
System.Int32
System.Int32
System.Int32
Using the unary operator to create a jagged array
$commaArray = ,#(1,2,3)
$commaArray.Count
$commaArray | ForEach-Object{$_.GetType().FullName}
1
System.Object[]
In the second example the array gets passed as a whole. PowerShell still unrolled it from a single array with one element that was itself an array to that single array 1,2,3.
There are other cases for its use as well. I would more commonly see regular arrays declared statically with 1,2,3 or sometimes the #() is needed depending. Result is the same for both of those.
,";" is a trick/shorthand to create an array (try (,";").GetType()). Why would you need this? Well, let's try calling Split with a list of values directly:
"abc".Split('a','b')
Cannot convert argument "count", with value: "b", for "Split" to type
"System.Int32": "Cannot convert value "b" to type "System.Int32".
Error: "Input string was not in a correct format.""
Doesn't work because the parameters are passed separately, rather than as a char[]. So could we use the comma trick to fix this?
"abc".Split((,'a','b'))
Cannot convert argument "separator", with value: "System.Object[]",
for "Split" to type "System.Char[]": "Cannot convert the
"System.Object[]" value of type "System.Object[]" to type
"System.Char"."
No, because we still have a type mismatch. That's because this approach is too clever for its own good. A much more readable way to create an array is the #() operator:
"abc".Split(#('a', 'b'))
And this calls the desired overload of Split.
The Split method has multiple overloads. The second example will create an array of string which will be convertet to an char[] because its only one character in the double quotes. However if you want to split by two characters, the second example won't work thus I wouldn't use it.
However, the PowerShell way to split is using -split:
$vals1 = $member -split ':'

converting string to number in powershell

I am trying to convert a string to a 2 decimal place value
I have a script that has a line of code which is
(get-mailboxdatabase xxx -status).databasesize
This returns the size something like
1.008 GB (1,082,195,968 bytes)
I want to be able to convert this to a number (1.008) and can't work out how to do it.
I know about ToGB() but that only works when running the script from EMS.
I need to be able to run the script in Powershell and not EMS as the script does other things.
How do I convert the value to a number?
TIA
Andy
If you're using implicit remoting (it sounds like you are), that's going to be a [string], so you'll need to use string methods.
'1.008 GB (1,082,195,968 bytes)' -replace '^([0-9.]+).+','$1'
1.008
This is very easy, just make a cast and divide with 1GB.
PS C:\> [int]"1082195968"/1GB
1,00787353515625
Or in your case
([int](get-mailboxdatabase xxx -status).databasesize)/1GB
You can convert numbers to the various number types using standard .NET framework types and conversions. For example:
> $var = [decimal]::Parse("1.008")
> $var.GetType().Name
Decimal
Extracting just that portion of the string from the input is a separate issue, and it's hard to tell from your question which is giving you trouble. To get just the number, you might use something like this:
$input = (get-mailboxdatabase xxx -status).databasesize
$strSize = $input.Split(' ')[0]
Or you can use a regular expression. It all depends on how variable your size is.
try this:
$val= (get-mailboxdatabase xxx -status).databasesize
[decimal]([regex]::Match( $val, '(^.+)GB' )).groups[1].value