none
Кодировка в PoSH при выводе в консоль RRS feed

  • Вопрос

  • Поставлена задача автоматизировать работу с адресными книгами МФУ Ricoh.

    Какого то нормального софта для автоматизации работы с ricoh нет, есть только SmartDeviceMonitor for Admin который умеет работать с адресной книгой в ручном режиме.

    В интернете есть скрипт для работы с адресными книгами.

    https://gallery.technet.microsoft.com/scriptcenter/Ricoh-Multi-Function-27aeea71

    Скрипт рабочий, работает на PoSH v3...5

    Основная проблема: неправильный вывод в консоль PoSH скрипта.

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

    (скрипт принимает параметры и выдает результаты только с латинскими буквами. кириллицу он не воспринимает)

    После долгих экспериментов выяснилось следующее.

    Если в куске скрипта:

    $get.Envelope.Body.getObjectsProps.objectIdList.arrayType = "itt:string["+$get.Envelope.Body.getObjectsProps.objectIdList.item.count+"]"
    [xml]$xml = iwr $url -Method Post -ContentType "text/xml" -Headers @{SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"} -Body $get -OutFile C:\temp\iwr_raw.txt -Passthru
    $xml.SelectNodes("//returnValue/item") | %{
    New-Object PSObject -Property @{
       EntryType = (%{$_.item} | ?{$_.propName -eq "entryType"}).propVal
       ID        = [int](%{$_.item} | ?{$_.propName -eq "id"}).propVal
       Index     = [int](%{$_.item} | ?{$_.propName -eq "index"}).propVal
       Name      = (%{$_.item} | ?{$_.propName -eq "name"}).propVal
       LongName  = (%{$_.item} | ?{$_.propName -eq "longname"}).propVal
       UserCode  = (%{$_.item} | ?{$_.propName -eq "auth:name"}).propVal
       Mail      = (%{$_.item} | ?{$_.propName -eq "mail:address"}).propVal
    }} | sort Index | ft -a
    

    Допишем вывод:

    -OutFile C:\temp\iwr_raw.txt -Passthru

    Получаем файл с кириллицей.

    После вывода :

    | sort Index | ft -a
    Получается:
    PS C:\Users\Morozov.Andrey> C:\TEMP\my1.ps1
    
    Name                            Index
    ----                            -----
    ???????????? ??.??.                 1
    ?????????????????? ??.??.           2
    ?????????????????? ??.??.           3
    ?????????????? ??.??.               4
    ?????????????????? ??.??.           5
    ???????????? ??.??.                 6
    ???????????? ??.??.                 7
    ?????????????? ??.??.               8
    ?????????????? ??.??.               9
    ???????????????? ??.??.            10
    ???????????? ??.??.                11
    ?????????????? ??.??.              12
    ?????????? ??.??.                  13

    Все варианты с

    chcp 65001

    [system.console]::OutputEncoding

    [system.console]::InputEncoding

    ... и прочее перепробованы.

    Прошу помочь побороть кодировку PoSh !!!!

    19 ноября 2015 г. 7:08

Ответы

  • Поправить основной скрипт, и будет счастье.

    Тогда заменить строку:

    [xml]$xml = iwr $url -Method Post -ContentType "text/xml" -Headers @{SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"} -Body $get -OutFile C:\temp\iwr_raw.txt -PassThru

    На:

    iwr $url -Method Post -ContentType "text/xml" -Headers @{SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"} -Body $get -OutFile C:\temp\iwr_raw.txt | Out-Null
    [xml]$xml = Get-Content C:\temp\iwr_raw.txt -Encoding utf8 -Raw
    

    • Помечено в качестве ответа Morozov A. _ 19 ноября 2015 г. 9:56
    19 ноября 2015 г. 9:51
    Отвечающий

Все ответы

  • В файле текст читаем? Если читаем, используем(для начала посмотреть вывод в консоли Get-Content C:\temp\iwr_raw.txt и если некорректный указать -Encoding) :

    [xml]$xml = Get-Content C:\temp\iwr_raw.txt

    или

    [xml]$xml = Get-Content C:\temp\iwr_raw.txt -Encoding utf8 -Raw



    • Изменено KazunEditor 19 ноября 2015 г. 7:46
    19 ноября 2015 г. 7:41
    Отвечающий
  • в файле

    C:\temp\iwr_raw.txt

    текст читаем.

    Кусочек теста из этого файла:

    <propName>index</propName><propVal>12</propVal></item><item><propName>name</propName><propVal>Горлова О.П.</propVal></item>


    делаем пробный вывод в консоль:

    $xmlout = $xml.SelectNodes("//returnValue/item") | %{ 
    New-Object PSObject -Property @{  
            Index = [int](%{$_.item} | ?{$_.propName -eq "index"}).propVal
            Name = (%{$_.item} | ?{$_.propName -eq "name"}).propVal
            }
    
      }
    $xmlout | sort Index | ft -a | out-file -encoding utf8 c:\temp\test2.txt

    Получаем файл

    c:\temp\test2.txt

    С таким содержимым:

    Name                            Index
    ----                            -----
    ???????????? ??.??.                 1
    ?????????????????? ??.??.           2
    ?????????????????? ??.??.           3
    ?????????????? ??.??.               4
    ?????????????????? ??.??.           5
    ???????????? ??.??.                 6
    ???????????? ??.??.                 7
    ?????????????? ??.??.               8

    19 ноября 2015 г. 7:54
  • Через Get-Content какой результат?
    19 ноября 2015 г. 8:47
    Отвечающий
  • через Get-Content такой же.

    Я пересмотрел в Notepad++ все возможные кодировки test2.txt - ничего там полезного нет. Максимум что удалось вытянуть это символ ~ или Ё.

    Вывод кодируется так: одна русская буква это два знака вопроса ??.

    ////////////

    Я в верху немного не правильно написал:

    вывод в файл

    $xmlout = $xml.SelectNodes("//returnValue/item") | %{ 
    New-Object PSObject -Property @{  
            Index = [int](%{$_.item} | ?{$_.propName -eq "index"}).propVal
            Name = (%{$_.item} | ?{$_.propName -eq "name"}).propVal
            }
    
      }
    $xmlout | sort Index | ft -a | out-file -encoding utf8 c:\temp\test2.txt

    если мы выводим данные: тут вывод всегда битый

    $xmlout | sort Index | ft -a

    неважно куда выводится - в файл или консоль.

    вначале думал на реализацию кода

    $xml.SelectNodes("//returnValue/item") | %{ 
    New-Object PSObject -Property @{  
            Index = [int](%{$_.item} | ?{$_.propName -eq "index"}).propVal
            Name = (%{$_.item} | ?{$_.propName -eq "name"}).propVal
            }

    но честно говоря никаких косяков тут не могу найти. вроде сделано все грамотно.

    второе что думаю: битый вывод в консоль от PoSh.

    На сколько я понял кодировка - проблемное место у PoSh.



    • Изменено Morozov A. _ 19 ноября 2015 г. 9:04
    19 ноября 2015 г. 9:02
  • Вывод:

    [xml]$xml = Get-Content C:\temp\iwr_raw.txt -Encoding utf8 -Raw

    $xmlout = $xml.SelectNodes("//returnValue/item") | %{ 
    New-Object PSObject -Property @{  
            Index = [int](%{$_.item} | ?{$_.propName -eq "index"}).propVal
            Name = (%{$_.item} | ?{$_.propName -eq "name"}).propVal
            }
      }
    $xmlout | sort Index | ft -a

    И часть вывода с русским текстом:
    Get-Content C:\temp\iwr_raw.txt -Encoding utf8 -Raw



    • Изменено KazunEditor 19 ноября 2015 г. 9:08
    19 ноября 2015 г. 9:06
    Отвечающий
  • вывод:

    PS C:\Users\Morozov.Andrey> Get-Content C:\temp\iwr_raw.txt -Encoding utf8 -Raw
    <?xml version="1.0" encoding="UTF-8" ?>
    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/so
    ap/encoding/"><s:Body><tns:getObjectsPropsResponse xmlns:tns="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory
    "><returnValue xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:itt="http://www.ricoh.co.jp/xm
    lns/schema/rdh/commontypes" soap-enc:arrayType="itt:property[][50]"><item xmlns:soap-enc="http://schemas.xmlso
    ap.org/soap/encoding/" xmlns:itt="http://www.ricoh.co.jp/xmlns/schema/rdh/commontypes" soap-enc:arrayType="itt
    :property[6]"><item><propName>entryType</propName><propVal>user</propVal></item><item><propName>id</propName><
    propVal>25</propVal></item><item><propName>index</propName><propVal>4</propVal></item><item><propName>name</pr
    opName><propVal>Беляева В.А.</propVal></item>

    это часть текста

    19 ноября 2015 г. 9:44
  • я не верю: я вижу русский текст!!!

    $get.Envelope.Body.getObjectsProps.objectIdList.arrayType = "itt:string["+$get.Envelope.Body.getObjectsProps.objectIdList.item.count+"]"
    [xml]$xml = iwr $url -Method Post -ContentType "text/xml" -Headers @{  SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"   } -Body $get -OutFile C:\temp\iwr_raw.txt -Passthru
    
    
    [xml]$xml = Get-Content C:\temp\iwr_raw.txt -Encoding utf8 -Raw
    
    $xmlout = $xml.SelectNodes("//returnValue/item") | %{ 
    New-Object PSObject -Property @{  
            Index = [int](%{$_.item} | ?{$_.propName -eq "index"}).propVal
            Name = (%{$_.item} | ?{$_.propName -eq "name"}).propVal
            }
      }
    $xmlout | sort Index | ft -a
         

    вывод:

    PS C:\Users\Morozov.Andrey> C:\TEMP\my2.ps1

    Name              Index
    ----              -----
    Драган Г.С.           1
    Дадайкина М.С.        2
    Бибарсова С.В.        3
    Беляева В.А.          4
    Зинатулин М.Б.        5
    Дюжева Н.В.           6

    19 ноября 2015 г. 9:47
  • каким образом ломается кодировка???

    Оригинальный код:

    $get.Envelope.Body.getObjectsProps.objectIdList.arrayType = "itt:string["+$get.Envelope.Body.getObjectsProps.objectIdList.item.count+"]"
    [xml]$xml = iwr $url -Method Post -ContentType "text/xml" -Headers @{  SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"   } -Body $get
    
    $xml.SelectNodes("//returnValue/item") | %{ 
    New-Object PSObject -Property @{  
            Index = [int](%{$_.item} | ?{$_.propName -eq "index"}).propVal
            Name = (%{$_.item} | ?{$_.propName -eq "name"}).propVal
            }
      } | sort Index | ft -a

    Новый код:

    $get.Envelope.Body.getObjectsProps.objectIdList.arrayType = "itt:string["+$get.Envelope.Body.getObjectsProps.objectIdList.item.count+"]"
    [xml]$xml = iwr $url -Method Post -ContentType "text/xml" -Headers @{  SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"   } -Body $get -OutFile C:\temp\iwr_raw.txt -Passthru
    
    [xml]$xml = Get-Content C:\temp\iwr_raw.txt -Encoding utf8 -Raw
    
    $xmlout = $xml.SelectNodes("//returnValue/item") | %{ 
    New-Object PSObject -Property @{  
            Index = [int](%{$_.item} | ?{$_.propName -eq "index"}).propVal
            Name = (%{$_.item} | ?{$_.propName -eq "name"}).propVal
            }
      }
    $xmlout | sort Index | ft -a


    • Изменено Morozov A. _ 19 ноября 2015 г. 9:50
    19 ноября 2015 г. 9:50
  • Поправить основной скрипт, и будет счастье.

    Тогда заменить строку:

    [xml]$xml = iwr $url -Method Post -ContentType "text/xml" -Headers @{SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"} -Body $get -OutFile C:\temp\iwr_raw.txt -PassThru

    На:

    iwr $url -Method Post -ContentType "text/xml" -Headers @{SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"} -Body $get -OutFile C:\temp\iwr_raw.txt | Out-Null
    [xml]$xml = Get-Content C:\temp\iwr_raw.txt -Encoding utf8 -Raw
    

    • Помечено в качестве ответа Morozov A. _ 19 ноября 2015 г. 9:56
    19 ноября 2015 г. 9:51
    Отвечающий
  • Спасибо ОГРОМНОЕ!

    Дальше буду разбираться как редактировать адресную книгу.

    Помимо вывода скрипт еще записывает данные.

    Попробую сделать вывод через временный файл..

    Объясните пожалуйста: почему нормально не отрабатывает с кириллицей такая часть кода?


    $get.Envelope.Body.getObjectsProps.objectIdList.arrayType = "itt:string["+$get.Envelope.Body.getObjectsProps.objectIdList.item.count+"]"
    [xml]$xml = iwr $url -Method Post -ContentType "text/xml" -Headers @{  SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"   } -Body $get
    
    $xml.SelectNodes("//returnValue/item") | %{ 
    New-Object PSObject -Property @{  
            Index = [int](%{$_.item} | ?{$_.propName -eq "index"}).propVal
            Name = (%{$_.item} | ?{$_.propName -eq "name"}).propVal
            }
      } | sort Index | ft -a

    Ведь по идее должен отрабатывать без всяких временных файлов:

    [xml]$xml = iwr ............
    $xml.SelectNodes("//returnValue/item")


    я видел что пытались делать так

     iwr $url -Method Post -ContentType "text/xml; charset=utf-8" 

    но у меня ничего не  вышло

    • Изменено Morozov A. _ 19 ноября 2015 г. 10:03
    19 ноября 2015 г. 10:00
  • Должен , но не обязан. Чтобы было наверняка, следует переписать используя net.webrequest класс , а не данный командлет.

    Также есть баг - Invoke-WebRequest ignores content encoding - https://connect.microsoft.com/PowerShell/feedback/details/807794/invoke-webrequest-ignores-content-encoding

    Можно попробовать:

    [xml]$xml = iwr $url -Method Post -ContentType "text/xml; charset=utf8" -Headers @{  SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"} -Body $get
    
    
    или
    
    [xml]$xml = iwr $url -Method Post -ContentType "text/xml" -Headers @{  SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"} -Body ([System.Text.Encoding]::UTF8.GetBytes($get))
    
    или
    
    iwr $url -Method Post -ContentType "text/xml" -Headers @{  SOAPAction="http://www.ricoh.co.jp/xmlns/soap/rdh/udirectory#getObjectsProps"} -outvariable resp
    
    [xml]$xml = [text.encoding]::utf8.getstring([text.encoding]::default.GetBytes($resp.Content))


    19 ноября 2015 г. 10:19
    Отвечающий
  • баг этот видел.

    но я наивно понадеялся на русский "авось пронесет".

    не пронесло )

    все три варианта не работают.

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

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

    решение через файл подходит как workarround, потом может и iwr починят.

    Еще раз спасибо за помощь!

    19 ноября 2015 г. 10:47