I have a requirement to increment to read and increment the pom.xml version by 1 using powershell script.
I was able to fetch the version value as for example: 1.0.123, but the type given here is string, when I try to convert it into Decimal or Double I am getting below error:
Code:
PS C:\Users\XXXX\Downloads> $finale
1.0.153
PS C:\Users\XXXX\Downloads> $finale.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
Error:
PS C:\Users\XXXX\Downloads> $finale1 = [Double]::Parse($finale)
Exception calling "Parse" with "1" argument(s): "Input string was not in a correct format."
At line:1 char:1
+ $finale1 = [Double]::Parse($finale)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : FormatException
The reason is 1.0.123 is not math. It is nether an integer, nor a double. It is simply a string that contains numbers and symbols. This is why you are getting the error.
See the following Help files:
About_Arithmetic_Operators
.NET Math Class
Using a [version] type is nice, but it is immutable. This code splits it into an array, increments the third (Build) number, and produces a string in $newfinale.
Note that this does not check to see if there is a third (Build) value. It will produce an exception if the $finale is '1.2'.
PS C:\> $finale = '2.3.4.5'
PS C:\> $a = $finale.split('.')
PS C:\> $a[2] = [int]$a[2] + 1
PS C:\> $newfinale = $a -join '.'
PS C:\> $newfinale
2.3.5.5
Related
I want to take the contents of an .md file and have it appear in the body of a generated email for outlook. I can generate the email just find but the body gives the following error and I have yet to find a work around.
Error:
The object does not support this method.
At line:6 char:1
+ $new.HTMLBody = $a
+ ~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
Code:
$out= New-Object -comObject Outlook.Application
# $sign= Get-Content "C:\Users\Roaming\Microsoft\Signatures\sign.htm"
$recipient= "user#.com"
$new= $out.CreateItem(0)
$new.Subject = "Meeting details"
$a = Get-Content -Path "c:\temp\file.md"
$new.HTMLBody = $a
$new.Recipients.Add($recipient)
$new.save()
# $new.HTMLBody += $sign
$display= $new.GetInspector
$display.Display()
To get around the error message you posted, you need to read your file as a string rather than an array of strings. The reason is because $new.Body expects a string. By default, Get-Content returns an array with each line of a file being an element of that array. You can change this behavior with the -Raw switch, which will read the contents as one string.
$a = Get-Content -Path "c:\temp\file.md" -Raw
If the -Raw switch changes the newline formatting, you can always just join the default Get-Content array with newline characters of your choosing.
$a = Get-Content -Path "c:\temp\file.md"
$new.HTMLBody = $a -join "`r`n"
You can see the type differences in your original code using the GetType() method available to PowerShell objects.
$a.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
$new.Body.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True String System.Object
I am calling restAPIs and some of them return multiple results, I am trying use Select-String to get the correct line in the Array, but it returns a matchinfo object with a value starting with #{... I can't get this value into a hashtable or object so I can extract a member from the string.
I tried converting the MatchInfo object to a string with out-string and then putting that result in a hashtable. Get following error:
Cannot convert the "
#{id=352475; href=/api/v1/exports/458234/export_files/352475; export_id=458234; status=Available}
" value of type "System.String" to type "System.Collections.Hashtable".
Have a PSCustomObject with the following contents:
PS C:> $_expFilesRet
href export_files
---- ------------
/api/v1/user_identities/289362/export_files {#{id=352475;
href=/api/v1/exports/458234/export_files/3...
The export files method of the above is
PS C:\> $_ExpFilesRet.export_files.getType();
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
with the following value:
PS C:\> $_expFilesRet.export_files
id href export_id status
-- ---- --------- ------
352475 /api/v1/exports/458234/exp... 458234 Available
278697 /api/v1/exports/357459/exp... 357459 Available
Attempted the following
PS C:\> $_temp=$_ExpFilesRet.export_files | select-string -pattern $_postret.export_files.export_id
PS C:\> $_temp
#{id=352475; href=/api/v1/exports/458234/export_files/352475; export_id=458234; status=Available}
PS C:\> $_temp=$_ExpFilesRet.export_files | select-string -pattern $_postret.export_files.export_id | out-str
ing -width 1000
PS C:\> $_temp
#{id=352475; href=/api/v1/exports/458234/export_files/352475; export_id=458234; status=Available}
PS C:\> [hashtable]$_temp=$_temp
Cannot convert the "
#{id=352475; href=/api/v1/exports/458234/export_files/352475; export_id=458234; status=Available}
" value of type "System.String" to type "System.Collections.Hashtable".
At line:1 char:1
+ [hashtable]$_temp=$_temp
+ ~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : MetadataError: (:) [], ArgumentTransformationMetadataException
+ FullyQualifiedErrorId : RuntimeException
I am trying to get the value of ID (352475) from the resulting string in $_temp.
Use Where-Object rather than Select-String to filter objects:
$_temp = $_ExpFilesRet.export_files |Where-Object export_id -eq $_postret.export_files.export_id |Select -Expand id
I am creating a function and sometimes, it will return a empty array as there is not result. This function may need to run with Invoke-Command for some scenario, such as run on a remote PC and etc.
But what i found that, when my function run under Invoke-Command with script block, it cannot return empty array, but just null.
So I have a try and find that, the Invoke-Command seems to not able to return empty array even though I do that explicitly.
For exmaple:
> $foo = #()
> $foo.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
> $foo = Invoke-Command -ScriptBlock { #() }
> $foo.GetType()
You cannot call a method on a null-valued expression.
At line:1 char:1
+ $foo.GetType()
+ ~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
> $foo -eq $null
True
So how can I return empty array in this scenario? Any mistake here? Or any trick here?
Just prepend the returning value with comma , (array construction operator). Then the return value will not get flattened into $null:
$foo = Invoke-Command -ScriptBlock { ,#() }
Per this Code-Golf tip, in PowerShell you can use scientific notation to easily generate numbers which are powers of 10: https://codegolf.stackexchange.com/a/193/6776
i.e. 1e7 produces the number 10,000,000.
If I pass this value to get-date (or alias date, for the purposes of code golf) I get a single second: i.e. date 10000000 => 01 January 0001 00:00:01.
Yet if I use the scientific notation, even with brackets (i.e. date (1e7)) I get an error:
Get-Date : Cannot bind parameter 'Date'. Cannot convert value "10000000" to type "System.DateTime". Error: "String was not recognized as a valid DateTime."
At line:1 char:6
+ date (1e7)
+ ~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-Date], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.GetDateCommand
Question
Is there a way to use scientific notation with the Get-Date's default (date) parameter?
This is because 1e7 gets outputed as a double, so you just have to cast it to an integer:
date ([int]1e7)
You can check that if you call the GetType method on the output:
(1e7).GetType() | Format-Table -AutoSize
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Double System.ValueType
Edit:
Shortest script probably is:
1e7l|date
This is taken from PetSerAls comment - just removed another character by using pipe instead of brackets.
I'd like to pull a specific statistics from a _Total (the CounterSamples) into a variable, in order to further parse it.
This is what I've tried.
Trying to index with [1] gives error further below.
Looping didn't seem to get me very far either.
cls
$statToCollect = '\Process(_Total)\IO Data Operations/sec'
Get-Counter $statToCollect
Write-Host "================"
$saveStats = Get-Counter $statToCollect
$ctrSamples = $saveStats[1].CounterSamples
Write-Host "$ctrSamples"
Write-Host "$($saveStats)"
Write-Host "================"
$diskStats = Get-Counter $statToCollect
$diskStatsLoopCounter = 1
foreach ($diskStat in $diskStats)
{
if ($diskStatsLoopCounter -eq 1)
{
write-host "$($diskStat.CounterSamples)"
}
$diskStatsLoopCounter = $diskStatsLoopCounter + 1
}
Results:
Timestamp CounterSamples
--------- --------------
12/29/2014 9:27:49 AM \\mpcname\process(_total)\io data operations/sec :
970.6265098029
================
Unable to index into an object of type Microsoft.PowerShell.Commands.GetCounter.PerformanceCo
unterSampleSet.
At C:\Users\neal.walters\Documents\DiskUtil.ps1:6 char:26
+ $ctrSamples = $saveStats[ <<<< 1].CounterSamples
+ CategoryInfo : InvalidOperation: (1:Int32) [], RuntimeException
+ FullyQualifiedErrorId : CannotIndex
Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSampleSet
================
Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSample
In your particular case $saveStats is only the one element.
PS C:\Users\mcameron> $saveStats.Count
1
Which is why this command would have returned null output as there is not a second.
PS C:\Users\mcameron> $saveStats[1]
Since there was only the one element either of the following options would have worked for this case.
PS C:\Users\mcameron> $saveStats[0]
PS C:\Users\mcameron> $saveStats
Also as for the line Write-Host "$($saveStats)" since $saveStats is an object and not a string it would not expand the way you expect. Pretty sure this occure because the ToString() is not overloaded to handle this so just the object type is outputted. Simply having $saveStats on its own would allow powershell to format it properly using its own built-in cmdlets.
PS C:\Users\mcameron> $saveStats
Timestamp CounterSamples
--------- --------------
12/29/2014 10:56:53 AM \\c3935\process(_total)\io data operations/sec :
27.7291444862573
Similar issue with the line write-host "$($diskStat.CounterSamples)" which has the same response as above.
As the other commenters and posters have said you most likely want one of the properties like CookedValue which can be easily converted to a string.
write-host "$($diskStat.CounterSamples.CookedValue)"
Using PowerShell version 4 on Windows 8.1:
Get-Counter returns a PerformanceCounterSampleSet and you can access the CounterSamples property to get an array of PerformanceCounterSample objects.
The particular property that you're interested in is CookedValue:
$statToCollect = '\Process(_Total)\IO Data Operations/sec'
$total = (Get-Counter $statToCollect).CounterSamples.CookedValue
This gets you the result as a double:
PS> $total
28.9450419770711
PS> $total.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Double System.ValueType