Powershell ошибка входная строка имела неверный формат

The issue occurs because your string includes double quotes, which you need to escape, either by entering them twice like this:

$MyQuery = "select a.asset_name as 'ASSET_NAME',b.asset_name AS 'ASSET', from positions a join appraisal b on b.asset_name LIKE CONCAT(""%"",a.asset_name,""%"") where a.unrealised!= 0 ;"

Or by putting a backtick character before them:

$MyQuery = "select a.asset_name as 'ASSET_NAME',b.asset_name AS 'ASSET', from positions a join appraisal b on b.asset_name LIKE CONCAT(`"%`",a.asset_name,`"%`") where a.unrealised!= 0 ;"

Alternatively you can use a here-string, which works by surrounding the string with @' and '@ (or @" and "@) and makes everything between these characters interpreted as part of the string block, regardless of what other characters you include:

$MyQuery = @'
    select a.asset_name as 'ASSET_NAME',b.asset_name AS
   'ASSET',
              from positions a 
              join appraisal b
              on b.asset_name LIKE CONCAT("%",a.asset_name,"%") where 
               a.unrealised!= 0 ;
'@

Note that with a here-string you can’t put anything on the same line after the opening @' and the closing '@ must be on a line on it’s own, and can’t have any whitespace before it.

If you use the double quoted version of the here string, you can still embed variables in the string and have them expanded.

For more information on here-strings see here.

When you want to convert a string to a secure string with ConvertTo-SecureString, you may get the
following error message

ConvertTo-SecureString : Input string was not in a correct format

Reason

This happens when you try to convert a regular string to a secure string.
“Convert To Secure String” string only means “to protect in memory”.

However, the standard input for the ConvertTo-SecureString cmdlet is an encrypted string.

Workaround

As a workaround you can use the AsPlainText parameter, which has to be associated with the Force
parameter (to confirm you understand the implications).

$MySecureString = ConvertTo-SecureString -String $MyPlainTextString -AsPlainText -Force

Получаю по API JSON результат. Но русские буквы отображаются в виде знаков вопроса.
Есть идеи, товарищи? Спасибо заранее

Что запускаю:

$url2 = "http://********/rooms?limit=3&access_token=******"
$rres = Invoke-WebRequest -Method GET -Uri $url2 -ContentType "application/json;charset=utf-8" | ConvertFrom-Json
$Lmres = $rres.chunk
Write-Host $Lmres[0].Content

Получаю:

@{body=???? ??????) ; msgtype=m.text}
@{body=??????????????; msgtype=m.text}
@{body=??????????; msgtype=m.text}

Кодировку запроса к json менял на win-1251, ничего не изменилось.

Viktor Tomilov's user avatar

Viktor Tomilov

8,3054 золотых знака25 серебряных знаков63 бронзовых знака

задан 28 фев 2018 в 6:36

technor's user avatar

В данной строке:

$rres = Invoke-WebRequest -Method GET -Uri $url2 -ContentType "application/json;charset=utf-8"

вы задаёте не кодировку отклика, а кодировку запроса. Нужно менять кодировку уже возвращаемых данных. Не могу сэмулировать именно ваш запрос, поскольку адрес неизвестен, но выглядеть это должно как-то так:

$rus_result =  [System.Text.Encoding]::GetEncoding('windows-1251').GetString([Byte[]]$your_result)

или то же самое, но с utf-8 вместо windows-1251

ответ дан 28 фев 2018 в 6:58

Viktor Tomilov's user avatar

Viktor TomilovViktor Tomilov

8,3054 золотых знака25 серебряных знаков63 бронзовых знака

2

Массивы в Powershell являются аналогами списков в Python. Легче всего воспринимать эти понятия как хранение в одной переменной множества значений. То есть это структура данных, которую можно перебирать и вызывать отдельный элемент используя индексы. Массивы, они же и множества и array, в Powershell и других языках программирования являются отдельным типом данных так же как числа и строки.

Создание

Массивы являются базовой возможностью Powershell, и их создание делается просто. Для создания нужно использовать символы @() :

$array = @()
$array.count

Создание массива в Powershell

Count (в переводе счетчик) — показывает сколько у нас элементов в массиве. Так как мы создали пустое множество он равен нулю.

Можно создать сразу со значениями. Что бы это выполнить нужно добавить значения, разделенные запятой, внутри @() :

$lst = @('Первый', 'Второй', 'Четвертый', 'Третий')
$lst.Count
$lst

powershell вывод массива

Написав $array мы вывели значения переменной. Каждое из четырех значений выводится с новой строчки. 

Другой способ создания — это писать значения с новой строчки. В этом случае запятые ставить не обязательно:

$lst = @('Первый'
            '2'
            'Третий'
            4)
$lst.Count
$lst

powershell элементов в массиве

 Хоть такая возможность и есть в Powershell, я бы не советовал использовать без запятых. В остальном, с использованием табуляции, такой синтаксис может улучшить читаемость (особенно если у нас сотни значений).

Еще один способ объявления — это не указывать скобки и знак @ :

$lst = '7',8,'Один','One'

powershell создать массив

Следующий вариант не используется на практике, но вы можете иметь его ввиду:

$lst = Write-Output Один 2 Трии '4'

powershell массивы

Обратите внимание, что число 4 стало строкой только тогда, когда ее поместили в кавычки.

Получение элементов

Как уже было показано выше получить весь массив можно написав переменную, но так же можно использовать другие методы как смещение и индексы.

Индексы

Когда нужно получить конкретный элемент мы указываем скобки []. Самое первое значение массива имеет идентификатор 0. На следующем примере мы получим первый объект:

$arraylist = 'Первый','Второй','Третий'
$arraylist[0]

Для получения следующих индексов просто измените число:

$arraylist[2]

powershell вывод массива

На примерах выше мы получили данные по их индексам. В отличие от большинства языков в Powershell мы можем указывать несколько индексов, которые хотим получить. Так же можно вызвать один и тот же элемент неограниченное количество раз:

$arraylist[0,2]

powershell массивы

Срез (slice) или последовательность — это когда мы получаем данные с одного индекса по другой. Последовательности обозначаются двумя точками ‘..’ . Для примера получим первые три значения:

$arraylist = @('admin@login', 'admin', 'Password', '20.02.2004', '????', '????')
$arraylist[0..2]
$arraylist[1..100]

powershell массивы

Как видно мы можем получить данные не в строгой последовательности относительно массива. Так же указав несуществующий индекс ‘100’ мы не получили ошибку, а вывели все значения с первого до последнего. Если вызвать единственный элемент, который не будет существовать, то значения будут равны Null.

$null -eq $arraylist[200]

В большинстве языков отрицательное число ‘-1’ обозначает последний объект массива. Обратите внимание, что использование [-1..0] и [0..-1] приведет только к получению первого и последнего элемента:

$arraylist[0..-1]
$arraylist[-1..0]

powershell создать массив

Можно указать -2 для получения предпоследнего объекта и т.д. Последний объект можно получить и таким образом:

$arraylist.GetUpperBound(0)

Если вы попытаетесь получить индекс у несуществующего массива, или с несуществующими значениями, то это может привести к разным последствиям:

$arraylist = $null,$null
$arraylist[0]
$arraylist = $null
$arraylist[0]

powershell array

Возможные ошибки:

  • Не удается индексировать в массив NULL.
  • Cannot index into a null array.

Если вы не совсем понимаете как работает NULL в Powershell, то советовал бы вам прочитать предыдущую статью.

Использование счетчика Count

Счетчик удобно использовать, когда мы хотим проверить количество элементов в массиве:

$lst = '0','2','3','4'
$lst.count

if ($lst.count -eq 4){Write-Output 'Hacked!'}

powershell элементов в массиве

Используя счетчик можно получить и элемент массива. Если вы никогда не работали с индексами обращайте внимание, что счетчик возвращает количество элементов в массиве, но индексация начинается с 0 элемента. То есть для получения последнего элемента нам нужно вычесть 1:

$lst[$lst.count - 1]
$lst[0..($lst.count - 1)]
$lst[2,($lst.count - 1)]

powershell string array 

Если вы не закроете в скобки выражение в случае получения среза, то будут следующие ошибки:

  • Сбой вызова метода из-за отсутствия в [System.Object[]] метода с именем «op_Subtraction».
  • Method invocation failed because [System.Object[]] does not contain a method named ‘op_Subtraction’.

Замена элементов

Для замены элементов так же нужно указать индекс. Если мы хотим заменить первый объект, то соответственно нужно указать индекс 0:

$data = @(7,5,8,4,5)
$data[0]=0
$data
$data[-1]='Пять'
$data

powershell arraylist

Указание несуществующего индекса вызовет ошибки:

  • Index was outside the bounds of the array
  • Индекс находился вне границ массива.

Итерации

Кроме индексов с массивом часто приходится работать используя циклы и другие методы перечисления. Далее будет рассказано об этом.

Конвейер или Pipeline

В примере ниже мы проверим доступность хостов передав каждый объект массива через конвейер:

$sites = 'localhost','fixmypc.ru'
$sites | ForEach-Object {ping $_}

powershell массив объектов

Цикл ForEach

В циклах массивы используются похоже:

foreach ($site in $sites)
{
ping $site
}

powershell массивы

Так же доступен метод foreach, который немного отличается синтаксисом, но работает так же:

$sites.foreach({ping $_})

Использование switch

Switch это аналог условий, который объединен в единую конструкцию. Мы можем объявить switch и передать в наш список:

$data = 'folder','hack'
switch( $data )
{
'folder' {'Создать папку с именем'; New-Item -Path 'C:\Array' -ItemType Directory}
'file' {'Создать файл'}
'hack' {'Взломать аську'; ping fixmypc.ru}
Default {'Ничего не создавать'}
}

powershell array

Обновление значений через циклы

Если нам понадобится обновить весь массив мы обратимся к циклам и мы можем столкнуться с трудностями. Проблемы заключаются в том, что в цикле находится не сам массив, а его значения и мы не сможем их изменить так. Обойти эту ситуацию можно двумя путями.

Первый способ — это обратиться к каждому значению по индексу, а саму ‘длину’ индексов измерить методами, которые описаны выше:

$val = @(1,2,3)
0..($val.Count-1) | foreach {$val[$_]=$val[$_] + 1}

powershell массивВ Powershell мы можем генерировать список из чисел указав только первое и последнее число и именно это я делал в следующей строке:

0..($val.Count-1)

В другой строке я указал заменить число под этим индексом на новое прибавив 1:

$val[$_]=$val[$_] + 1

Еще один способ через ‘for’, который практически не применяется PS:

for ( $index = 0; $index -lt $array.count; $index++ )
{
$array[$index] = ($array[$index] + 1) -f $array[$index]
}

powershell создать массив

Использование объектов в массиве

В предыдущих примерах мы рассматривали работу с типами данных, но массивы могут хранить любые данные и объекты. Такие методы удобно использовать, когда собираете много данных и часто с ними работаете:

$data = @(
[pscustomobject]@{Computer='localhost';Login='admin';Process=Get-Process -ComputerName 'localhost'},
[pscustomobject]@{Computer='127.0.0.1';Login='lizun';Process=Get-Process -ComputerName '127.0.0.1'}
)
$data

powershell массив объектов

Вызвав переменную вы увидите, что представление данных почти не отличается от вывода командлетов.

Для получения данных мы можем указывать индексы:

$data[0]

После получения объекта вызвать свойство (‘колонку’ с примера выше), которое нам нужно:

$data[0].Computer
$data[0].Process

powershell массив объектов

Когда нужно будет получить, например, все имена компьютеров используем циклы:

$data | ForEach-Object {$_.Computer}

Можно вызвать напрямую или командлет Select-Object:

$data | select Computer
$data.Computer

powershell массив объектов

Фильтрация массивов через Where-Object

Фильтрация можно использовать, например, когда нам нужно найти все цифры из массива наполненным разными данными. На следующем варианте видно, что она мало чем отличается от того, что мы применяем в командлетах:

$list = @(
[pscustomobject]@{Name='Dima';SubName='Penkin'},
[pscustomobject]@{Name='Valera';SubName='Lerov'}
)
$list | where {$_.Name -like 'D*' -and $_.SubName -like '*n'}
$list | Where-Object SubName -eq 'Lerov'

powershell поиск в массиве

Аналогично способу выше есть метод, который фильтрует так же:

$list.Where({$_.Name -eq 'Dima'})

Обновление объектов через цикл

При использовании циклов таким способом мы будем обновлять значение Name во всех значениях массива:

foreach($iden in $list)
{
$iden.Name = 'Sasha'
}

powershell массивы замена

Если вы хотите заменить конкретное свойство, нужно использовать условия:

$list = @(
[pscustomobject]@{Name='Dima';SubName='Penkin'},
[pscustomobject]@{Name='Valera';SubName='Lerov'}
)
foreach($iden in $list){
if ($iden.Name -eq 'Dima'){$iden.Name='dd'}
}
$list

powershell массивы замена

Заменить весь объект используя цикл нельзя.

Операторы

-join

Join это оператор, который может преобразовать весь массив в единую строку где разделителем может быть любой символ:

$string_array = @('Masha', 'Sasha', 'Dima')
$string_array -join '.'
$string_array -join ' пошел к '

powershell строку в массив

Следующие варианты просто сольют все символы в одну строку без пробелов:

$string_array = @('Masha', 'Sasha', 'Dima')
$string_array -join $null
-join $string_array

 Можно использовать для логирования ошибок:

$data = @((Get-Date).Day, 'Error 5051', (hostname))
"Ошибка $data"

powershell двумерный массив

-replace

Операторы замены проверит каждый элемент и выполнят замену совпадающих значений:

$massive = 'Lena','Misha','Pika'
$massive -replace 'M','S'
$massive.Replace('L','p')

powershell массивы замена

Более подробно мы уже говорили о replace с Powershell.

-split

Split преобразует строку в список. В качестве разделителя я указал пробел:

$massive = 'Преобразование строки'
$massive -split ' '
$massive.Split(' ')

powershell строку в массив

-contains 

Этот оператор проверяет точное вхождение и возвращает булево значение True или False:

$list = 'Вася','Федя'
# Верно
$list -contains 'Вася'
# Не верно
'Вася' -contains $list

powershell поиск в массиве

-in

Отличия от contains в том, что он появился в Powershell 3 и создан для более удобной читаемости. В операторах Powershell важно соблюдать позиции того что мы ищем и где. Ошибки могут быть очень неявными. В случае с contains объект должен находиться слева, а в in справа:

$list = 'Вася','Федя'
# Верно
'Вася' -in $list
# Не верно
$list -in 'Вася'

powershell поиск в массиве

Этот оператор так же можно использовать для поиска в массиве Powershell.

 -eq и -ne

При использовании сравнения ‘eq’ у нас вернется либо само значение, либо False. В случае неравенства ‘ne’ вернутся либо остальные значения, либо True. Важно использовать искомое значение справа, а объект слева:

$data = @('один','два','три')
# Верно
$data -eq 'один'
$data -ne 'один'
# Не верно
'один' -eq $data
'один' -ne $data

powershell сравнение массива

Если нужно проверить, что все значения в листах совпадают требованиям, можно воспользоваться такой конструкцией:

$array = @('Ok','Ok','not Ok')
if ( -not ( $array -ne 'Ok') ){'Что-то не так, это False'}

$array = @('Ok','Ok','Ok')
if ( -not ( $array -ne 'Ok') ){'Все ок'}

powershell сравнение массива

-match и -like

Оператор match позволяет использовать регулярные выражения. Он будет искать каждое совпадение в массиве и вернет их:

$var = @('QQ-11-22','22-44-SS','FF-GG-HH')
# Верно
$var -match '22'
# Не верно
'22' -match $var

powershell поиск в массивеВ операторе like можно использовать знак *, который будет идентифицировать пропущенный текст. Следующий пример сработает с ошибкой в случае с match:

$var = @('QQ-11-22','22-44-SS','FF-GG-HH')
# Верно
$var -like '2*S'
# Не верно
'2*S' -like $var

powershell поиск в массивеПохоже сработает Select-String:

$var = @('QQ-11-22','22-44-SS','FF-GG-HH')
$var | Select-String 22

Проверка $null

Если мы будем проверять существующий массив, в котором нет значений, то следующий пример вернет False:

$foo = @()
if($foo -eq $null) { "Пустой" } else { "Значения есть" }

Он так же вернет False, если внутри будет $null:

$foo = @($null)
if($foo -eq $null) { "Пустой" } else { "Значения есть" }

Что бы избежать ошибок нужно добавлять счетчик:

if ( $foo -ne $null -and @($foo).count -gt 0 ){'Все по маслу'}

powershell массив $null

Сортировка массива

Для сортировки в Powershell используется командлет Sort-Object:

$sort = 4,7,3,2,4
$sort | Sort-Object
$sort = 'V','F','A'
$new_sort = $sort = 'V','F','A' | Sort-Object

Более подробно командлет Powershell Sort-Object уже рассматривался.

Добавление элементов в массив Powershell

Фактически Powershell не позволяет добавлять элементы в массив. Для того что бы это сделать массив сначала удаляется, а затем создается новый. Возможно кому-то будет более понятно это под «неизменяемый объект». Тем не менее процесс удаления и создания сильно упрощен в PS и вам не составит труда это сделать.

Сложение

Для создания нового массива можно указать оператор сложения для двух существующих:

$a = @('1')
$b = @('2','4')
$c = $a + $b
$c

Другой способ существует во множестве языках:

$array_add = @('1')
$array_add += 2
$array_add

powershell добавить в массив

Создание из конвейера

 Можно генерировать новый массив используя старый:

$array_add = @(0)
1..5 | ForEach-Object { $array_add+=$_ }
$array_add

powershell использование конвейера в массиве

Типы массивов

По умолчанию массив в Powershell создается типа [PSObject[]]. Это позволяет хранить любые типы данных. Если вы хотите хранить строгие типы данных, например только числа или определенный набор, то вы можете использовать следующие методы:

Массив из определенных типов данных

Используя следующий методы можно создать любой массив со строгими типами данных. Пример ниже позволяет использовать только числа:

[int[]] $num = 9,2,3,'4'

Обратите внимание, что 4 объявлена строковой, но она сама преобразуется в число без ошибок. В случае добавления букв будет ошибка:

  • Не удается преобразовать значение «s» в тип «System.Int32». Ошибка: «Входная строка имела неверный формат.»
  • Cannot convert value «s» to type «System.Int32». Error: «Input string was not in a correct format.»

Так же можно сделать и со строками, но в таком случае все добавленные данные преобразуются в строки:

[string[]] $str = '8','s','d'
$str+= 1

массив из строгих типов данных в Powershell

Универсальные списки

Универсальные списки относятся к C#, в котором нужно определять типы данных. Так мы создадим список из строк:

$list = [System.Collections.Generic.List[string]]::new()

А так будет создан список из целых чисел:

$list = [System.Collections.Generic.List[int]]@(32,55,66)

Начиная с версии Powershell 5 можно сократить синтаксис используя using namespace. Using указывается в самом начале скрипта. 

using namespace System.Collections.Generic
$list = [List[int]]@(31,32,33)

Списки Powershell

Следующий синтаксис добавит число в список:

$list.Add(10)

Значения так же можно получать по индексам:

$list[-1]

Списки Powershell

Для удаления используется следующий синтаксис:

using namespace System.Collections.Generic
$var = [List[string]]@('Один','Два','Три')
[void]$var.Remove('Один')

Можно так же удалять по индексам:

$delete = $var[1]
$var.remove($delete)

Списки Powershell

List[PSObject]

Список из любого типа данных можно создать и так:

using namespace System.Collections.Generic
$list = [List[PSObject]]::new()

Списки Powershell

ArrayList

Для поддержки удаления, которого нет в обычных массивах, можно использовать ArrayList. Они так же быстрее работают. Для создания такого массива используйте следующий синтаксис:

$arraylist = [System.Collections.ArrayList]::new()
[void]$arraylist.Add('Someval')
$arraylist

Для удаления:

$arraylist.Remove('Someval')

Другие методы по работе с массивами

Кроме основных методов по работе с массивами есть методы, которые позволяют генерировать списки и создавать фиксированного размера. Далее разберем на примерах.

Фиксированный размер

В Powershell можно создать список с предопределенным размером:

$data = [Object[]]::new(5)
$data.count

Списки Powershell

Умножение

Так же как и в других языках массивы можно умножать:

$var = @('A','B','C')
$var*5

Похожий метод, который создаст 10 нулей:

[int[]]::new(10)

Генерирование массивов

Вложенность

Массив внутри других массивов называются вложенными. Работа с ними отличается только индексами:

$array = @(
@(2,2,2),
@(3,3,3)
)

Чтобы получить значение нужно использовать индексы дважды:

$array[0][1]
$array[1][1]

powershell массив строк

Учитывая это можно создать двумерный массив.

Двумерные массивы и многомерные

Учитывая предыдущие примеры мы сможем создать двумерный массив или матрицу:

$dv_massive = @(
@(1,2,3,4),
@(3,4,5,6),
@(7,8,9,10)
)

Для получения, например, единицы нам нужно использовать индексы дважды:

$dv_massive[0][0]

Если вызвать весь массив, то он будет выведен построчно. Можно вывести и так:

ForEach($el in $dv_massive){Write-Host $el[0] $el[1] $el[2] $el[3]}

powershell двумерный массив

Можно вывести указав SyncRoot:

$dv_massive | select SyncRoot

Многомерный массив можно создать и вывести с параметрами так:

$ma_massive = New-Object 'object[,]' 5,3
# Внесение в первую колонку
$ma_massive[0,0] = 1
$ma_massive[1,0] = 2
$ma_massive[2,0] = 3
$ma_massive[3,0] = 4
$ma_massive[4,0] = 5
# Во вторую
$ma_massive[0,1] = 'A'
$ma_massive[1,1] = 'B'
$ma_massive[2,1] = 'C'
$ma_massive[3,1] = 'D'
$ma_massive[4,1] = 'E'
# Третью
$ma_massive[0,2] = 1988
$ma_massive[1,2] = 1999
$ma_massive[2,2] = 1876
$ma_massive[3,2] = 1478
$ma_massive[4,2] = 1247
# Вывод
Write-Host $ma_massive[0,0] $ma_massive[0,1] $ma_massive[0,2]
Write-Host $ma_massive[1,0] $ma_massive[1,1] $ma_massive[1,2]
Write-Host $ma_massive[2,0] $ma_massive[2,1] $ma_massive[2,2]
Write-Host $ma_massive[3,0] $ma_massive[3,1] $ma_massive[3,2]
Write-Host $ma_massive[4,0] $ma_massive[4,1] $ma_massive[4,2]

powershell двумерный массив 

Теги:

#powershell

Понравилась статья? Поделить с друзьями:
  • Powershell контроль ошибок
  • Powerpoint exe системная ошибка
  • Powershell ошибка test connection
  • Powerman online 1000 коды ошибок
  • Powershell обработка ошибок