Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Переменные из данных в txt файле (http://forum.oszone.net/showthread.php?t=300586)

breakfruit 01-06-2015 16:43 2513812

Переменные из данных в txt файле
 
Всем доброго времени суток. Для меня, по-прежнему, PoSH - дремучий лес. И вновь появилась (поставили:) ) интересную задачу.

Есть txt файл с некими параметрами
Код:

Id                : 39d525ee-de75-446c-84bd-0d0ff08d3b8d
TypeOfRule        : IP
VMId              : e0f63469-1c5e-4c8e-a0ae-5b92e7cfe1da
Name              : ICMP Allow in
Description      :
Direction        : Inbound
Action            : Allow
LocalPorts        : {0-65535}
RemotePorts      : {0-65535}
RemoteVMs        : {}
TargetAddressType : Any
VlanId            : 4095
Protocol          : ICMP
ProtocolNum      : 1
ProtocolString    : ICMP
RemotePortsString : 0-65535
LocalPortsString  : 0-65535
RemoteIPs        : Any
RemoteMACString  : Any

Нужно задать переменные, используя почти все указанные значения полей в файле. Т.е. то, что после ":" идет. Я так понимаю, тут потребуется уже что-то более серьезное, чем foreach, который я уже худо бедно освоил. Но вот что именно, загуглился уже весь.

Заранее признателен за любую помощь. А если еще и наводка будет на то, что почитать. Конкретно по данной тематике - с меня напитки и плюшки по почте России :D

Kazun 01-06-2015 17:48 2513827

Код:

PS > $val = (Get-Content f.txt) -replace " : ","=" | ConvertFrom-StringData
PS > $val.id
39d525ee-de75-446c-84bd-0d0ff08d3b8d

PS > $val.Name
ICMP Allow in


breakfruit 01-06-2015 18:01 2513832

Kazun, примного благодарен! Это очень полезно, но я, в виду понедельника, не все вводные сказал. В текстовом файле таких таблиц может быть две и более. В этом случае, я так понимаю, результат будет другим...


Т.е. Поля те же - значения разные.

greg zakharov 01-06-2015 18:50 2513847

breakfruit, так Вам что, собственно, нужно: рандомная выборка из оных таблиц или какое-то определенное свойство? И потом, фраза "я так понимаю" обычно подразумевает некое размытое представление некой концепции. Чтобы понять происходящее:
Код:

PS> $a = (gc foo) -replace':','=' | ConvertFrom-StringData
#используйте метод объекта GetType
PS> $a.GetType()


Iska 01-06-2015 22:13 2513914

Цитата:

Цитата breakfruit
но я, в виду понедельника, не все вводные сказал. В текстовом файле таких таблиц может быть две и более. »

Ждём от Вас подобный файл, упакованный в архив и либо прикреплённый к сообщению, либо выложенный на RGhost.

breakfruit 02-06-2015 08:15 2513988

Вложений: 1
greg zakharov, не совсем рандомная. Есть сторонний командлет, в котором отсутствует команда ЭКспорта / импорта. РЕчь о FireWallе.
Цитата:

Цитата greg zakharov
И потом, фраза "я так понимаю" обычно подразумевает некое размытое представление некой концепции »

а оно, увы, так и есть... Так как без толковой теории я сразу перешел к практике. Увы, времени мало, и курсов никто не оплачивает. Кризис же. Потом используем то, что имеем. Гугл, PoSH ISE + развиваем логику.


По порядку.
1. Есть группа (не просто выборка клиентов, а именно группа, в которую включены клиенты) юнитов у которых есть определенные правила. Условно Г1
2. Необходимо эти правила скопировать для другой группы юнитов. Условно Г2

Моя идея в том, что бы:
1. Экспортировать правила в txt
2. Распарсить его
3. Значению каждого поля задать переменную
4. Применить правила используя, полагаю, foreach.

Это пока все, до чего я додумался.

Правила в FireWall создаются на основе VmID (второе поле в выгруженном файле).

Iska, пример в аттаче.

Файл 125738

Kazun 02-06-2015 08:20 2513989

Используйте Export-CliXml и на требуемой машине Import-Clixml, так избежите подобных проблем.

Если формат неизменен txt:

Код:

$d = (Get-Content ParentGroupRules.txt) -match " : "

$val = for($i = 0; $i -lt $d.count; $i+=19)
{
        ($d[$i..($i+19)] | Out-String) -replace " : ", "=" | ConvertFrom-StringData
}

PS C> $val[0].Name
DNS traffic
PS > $val[1].Name
HTTP traffic
PS > $val[1].VlanId
4095


breakfruit 02-06-2015 08:42 2513995

Kazun, не совсем понял "Если формат неизменен txt"? В смысле, что дальше код идет при условии выгрузки в txt файл? Если использовать CliXml - скрипт будет отличаться, правильно я понимаю?

Kazun 02-06-2015 09:17 2514005

FireWallе | Export-CliXml -Path rules.xml

Переходим на другую машину и выполняем:

$val = Import-CliXml -Path rules.xml

breakfruit 02-06-2015 09:23 2514008

Kazun, попробую. Отпишусь по результатам.

breakfruit 02-06-2015 10:23 2514028

Kazun, в общем скрипт отрабатывает без ошибок НО

Код:


$script:vmgroup=Get-VMgroups | where {$_.name -like "ad*"} | select -ExpandProperty ID

        Get-Rules -VMId $groupID | Export-Clixml -path c:\rules10.xml

$script:vmgroup2=Get-VMGroups | where {$_.name -like "web*"} | select -ExpandProperty ID
        Add-IPRule | Import-Clixml -path C:\rules10.xml

На этапе добавления правил - запрашвиает параметры для ввода. Практически все поля, указанные в экспортированном файле - обязательны для ввода, но командой командлетом фаервола - Import не воспринимается... Т.е. после выполнения Add-IPRule начинается запрос ввода данных.

Полагаю, что еще и парсинг XML придется почитать...

Kazun 02-06-2015 12:18 2514070

Get-Help Add-IPRule -Full - смотрим какие параметры требуется передать командлету.
Код:

Import-Clixml -path C:\rules10.xml | Foreach {Add-IPRule -Name $_.Name -Action $_.Action}

breakfruit 02-06-2015 13:17 2514100

Kazun, наводка отличная. Ман прочитал, но... Команда данная ровным четом не выполняет нужной функции, так как ADD-IPrule продалжает запрашивать необходимые параметры, но такой код
Код:

$script:vmgroup=Get-VMgroups | where {$_.name -like "ad.*"} | select -ExpandProperty ID

        Get-Rules -VMId $vmgroup | Export-Clixml -path c:\rules10.xml

$script:vmgroup2=Get-VMGroups | where {$_.name -like "web*"} | select -ExpandProperty ID

$script:inputdata=Import-Clixml -path C:\rules10.xml



foreach ($VMid in $InputData)
       
       
        {
        Add-IPRule -VMId $vmid.vmid -Name $vmid.name -Action $vmid.action -Description $vmid.description -Protocol $vmid.protocol
        }

Делает то, что нужно, с оговоркой: правила дублируются в ту же группу, а не в другую. Я ужде в конец запутался. Вроде все корректно в коде. И поле нужное (VMId в данном случае указывает на ID группы) выцепил (проверил четырежды).

breakfruit 02-06-2015 15:43 2514169

Нашел свою ошибку. Дальше пошли танцы со сторонним командлетом. Помечаю тему, как решенную. Всем спасибо за участие!

greg zakharov 02-06-2015 17:57 2514230

Цитата:

Цитата breakfruit
...продалжает запрашивать необходимые параметры...

Если командлету передается довольно много параметров, то избежать головной боли - а главное спагетти-кода - можно, да и нужно, использовать тип Hashtable, например
Код:

PS> $par = @{
>> Path = 'E:\*'
>> Force = $true
>> }
>>
PS> gci @par

Особенно удобно использовать данный подход, как было сказано, при передаче большого количества параметров и дальнейшей отладке, не говоря уже о простоте "изъятия" одного из них.

breakfruit 03-06-2015 17:05 2514626

greg zakharov, сейчас очень интересно, но я мало чего понял...

Т.е. я понимаю, о каких спагетти речь (они фактически и получились) - но все остальное....

greg zakharov 03-06-2015 18:18 2514645

breakfruit, прошу прощения, если сформулировал мысль не достаточно четко. Попробую объяснить популярно на пальцах. Допустим есть командлет, которому нужно скормить более одного параметра за раз. Например:
Код:

Invoke-Cmdlet -Param1 one -Param2 two ... -ParamN N
Иными словами, чем больше параметров, тем длиннее спагетти, а следовательно сложнее в отладке код. Чтобы сделать код более удобочитаемым параметры командлету можно передать в виде хэш-литерала, т.е. код выше можно переписать как:
Код:

$par = @{
  Param1 = 'one'
  Param2 = 'two'
  ...
  ParamN = N
}

Invoke-Cmdlet @par

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

breakfruit 04-06-2015 08:35 2514776

greg zakharov, во. Я попоутно читаю, конечно же, литературу и блоги на тему PoSH. Т.е. мы создаем переменную и задаем значением оной - массив параметров? Или я путаюсь в определениях? Суть кода я понял, но (так как я ОЧЕНЬ далек от кодинга в принципе, и по образованию воообще никому не нужный гуманитарий :D ) в определениях, видимо, путаюсь.

Iska 04-06-2015 08:40 2514778

breakfruit, верно. Только не «массив», а «хэш-таблица» (набор пар «имя-значение»).

breakfruit 04-06-2015 08:48 2514781

Iska, и любой командлет (даже стороннего разработчика) будет его нормально воспринимать? Т.е. это приемущество непосредственно PoSH, которое не зависит от командлетов?

Foreigner 04-06-2015 10:22 2514806

breakfruit, Должен любой, в том числе скрипты, если в них правильно оформлены параметры -- param ()

breakfruit 04-06-2015 10:27 2514810

*ушел гуглить правильность оформления параметров*

Всем еще раз огромное спасибо.

breakfruit 05-06-2015 11:31 2515200

Всем привет еще раз. С вами - заметки начинающего PoSH'ера.

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

foreach ($hGroup in $InputData)
             
        {
            Add-IPRule -VMId $dGroup_ID -Name $hGroup.name -Action $hGroup.action -Description $hGroup.description -Protocol $hGroup.protocolNum -Type $hGroup.Direction -LocalPorts $hGroup.LocalPortsString -RemotePorts $hGroup.RemotePortsString
        }

По совету бывалых, попытался убрать через хэш-таблицу. Получилось следующее. Немного изменив переменные
Код:

$ruleset= @{
"VMId" = "$dGroup_ID";
"Name" = "$Group.name";
"Action" = "$Group.action";
"Describtion" = "$Group.description";
"Protocol" = "$Group.protocolNum";
"Type" = "$Group.Direction";
"LocalPorts" = "$Group.LocalPortsString";
"RemotePorts" = "$Group.RemotePortsString";
}



foreach ($Group in $InputData)
             
        {
            Add-IPRule @ruleset
        }

В итоге - получаю ошибку, гласящуую, что
Код:

Add-IPRule : Cannot bind parameter 'Action'. Cannot convert value "Allow KERBEROS.action" to type "(убрал, дабы не было рекламы.VirtualFirewall.CommonDataTypes.RuleAction". Error: "Unable to match the
identifier name Allow KERBEROS.action to a valid enumerator name.  Specify one of the following enumerator names and try again: AllowNoSPI, Block, Allow"

Я понимаю, что проблема в том, что почему-то в параметр Action валится значения параметра Name, но я хоть убей понять не могу - почему?
После выполнения кода, даже с ошибками, картина переменных следующая

PS> $group.name
Allow KERBEROS

PS> $group.action

Value
-----
Allow

Kazun 05-06-2015 11:34 2515203

Не туда вынесли и не надо двойных кавычек:
Код:

foreach ($Group in $InputData)
{
$ruleset= @{
"VMId" = "$dGroup_ID";
"Name" = $Group.name;
"Action" = $Group.action;
"Describtion" = $Group.description;
"Protocol" = $Group.protocolNum;
"Type" = $Group.Direction;
"LocalPorts" = $Group.LocalPortsString;
"RemotePorts" = $Group.RemotePortsString;
}
Add-IPRule @ruleset
}


breakfruit 05-06-2015 11:43 2515211

Т.е. хэш-таблица должна быть прописана внутри функции, всегда? Нельзя ее определить изначально?

Foreigner 05-06-2015 17:10 2515312

breakfruit, Имхо не обязательно:
Код:

$par = @{ Path = 'D:'; Force = $true }

function test {

    gci @par

}

test



Время: 15:03.

Время: 15:03.
© OSzone.net 2001-