Modelo para um bot de telegrama simples para alunos do 7º ao 9º ano usando Powershell
Durante conversas com um amigo, de repente descobri que as crianças da 8ª à 10ª série de sua escola não aprendem programação. Word, Excel e tudo mais. Nenhum logotipo, nem mesmo Pascal, nem mesmo VBA para Excel.
Fiquei muito surpreso, abri a Internet e comecei a ler - Uma das atribuições de uma escola especializada é promover a educação de uma nova geração que atenda às condições da sociedade da informação no seu nível de desenvolvimento e estilo de vida.
Esta unidade curricular permitirá aos alunos consolidar na prática os conhecimentos das construções básicas da linguagem de programação Pascal. (do programa de algum ginásio para 2017)
No final, decidi passar algumas horas esboçando um exemplo de “como criar um bot simples para crianças em idade escolar”.
Abaixo está como escrever outro bot simples no Powershell e fazê-lo funcionar sem webhook, IPs brancos, servidores dedicados, máquinas virtuais implantadas na nuvem e assim por diante - em um PC doméstico normal com Windows normal.
TLDR: Outro artigo chato com erros gramaticais e factuais, nada para ler, sem humor, sem imagens.
Não há nada de novo no artigo, quase tudo o que foi escrito antes já esteve no Habré, por exemplo em artigos Instruções: Como criar bots no Telegram и Bot Telegram para administrador do sistema.
Além disso, o artigo é deliberadamente redundante para não se referir sempre à literatura educacional. Não há referências ao Gang 4, PowerShell Deep Dives ou, digamos, The 5 Pillars of the AWS Well-Architected Framework no texto.
Em vez de um prefácio, você pode pular
Sinta-se à vontade para pularEm 2006, a Microsoft lançou o PowerShell 1.0 para os então Windows XP, Vista e Server 2003. De certa forma, ele substituiu scripts cmdbat, scripts vb, Windows Script Host e JScript.
Mesmo agora, o PowerShell só pode ser considerado o próximo passo após as opções do Logo, em vez do provavelmente ainda usado Delphi (ou algo mais antigo), apesar da presença de loops, classes, funções, chamadas MS GUI, Integração Git e assim por diante.
O Powershell é usado relativamente raramente; você só pode encontrá-lo na forma de PowerShell Core, VMware vSphere PowerCLI, Azure PowerShell, MS Exchange, Desired State Configuration, Acesso Web do PowerShell e cerca de uma dúzia de programas e funções raramente usados. Talvez ele ganhe fôlego com o lançamento WSL2, mas não é exatamente.
O Powershell também tem três grandes vantagens:
É relativamente simples, há muita literatura e exemplos sobre o assunto, e até em russo, por exemplo, um artigo sobre Foreach - do livro PowerShell em profundidade - sobre a diferença () e {}
Ele vai com o editor ISE, incluído no Windows. Existe até algum tipo de depurador lá.
Como todo mundo já sabe disso, e já aconteceu, você também pode pularConforme afirmado no artigo acima - Em primeiro lugar, um bot para Telegram - ainda é um aplicativo rodando do seu lado e fazendo solicitações à API do Telegram Bot. Além disso, a API é clara: o bot acessa uma URL específica com parâmetros e o Telegram responde com um objeto JSON.
Problemas relacionados: se de alguma forma desconhecida você pegar algum código de um objeto JSON e de alguma forma enviá-lo para execução (não de propósito), o código será executado para você.
O processo de criação está descrito em dois artigos acima, mas repito: em um telegrama abrimos contatos, procuramos @botfather, informamos a ele /newbot, criamos um bot Botfortest12344321, chamamos de Mynext1234bot, e recebemos uma mensagem com uma chave única do formulário 1234544311:AbcDefNNNNNNNNNNNNNN
Cuide da chave e não a entregue!
Aí você pode configurar o bot, por exemplo, proibir adicioná-lo a grupos, mas nos primeiros passos isso não é necessário.
Vamos pedir “/mybot” ao BotFather e ajustar as configurações se não gostarmos de algo.
Vamos abrir os contatos novamente, encontrar lá @Botfortest12344321 (é obrigatório iniciar a busca com @), clicar em “iniciar” e escrever para o bot “/Glória aos robôs”. O sinal / é obrigatório, as aspas não são necessárias.
O bot, claro, não responderá nada.
Vamos verificar se o bot foi criado e abri-lo.
api.telegram.org/bot1234544311:AbcDefNNNNNNNNNNNNNN/getMe
onde 1234544311:AbcDefNNNNNNNNNNNNNN é a chave recebida anteriormente,
e obter uma linha como
{"ok":true,"resultado":{""}}
Temos a primeira frase secreta (token). Agora precisamos descobrir o segundo número secreto - o ID do chat com o bot. Cada chat, grupo, etc. é individual e possui seu próprio número (às vezes com menos - para grupos abertos). Para descobrir este número, precisamos solicitar no navegador (na verdade não é necessário no navegador, mas para um melhor entendimento você pode começar por ele) o endereço (onde 1234544311:NNNNNNNNNN é o seu token
Vamos verificar se podemos escrever no chat manualmente: chame o endereço do navegador
https://api.telegram.org/botваштокен/sendMessage?chat_id=123456789&text="Life is directed motion"
Se você receber uma mensagem de um bot em seu chat, tudo bem, você passa para a próxima etapa.
Desta forma (através do navegador) você sempre pode verificar se há problemas na geração do link, ou se algo está escondido em algum lugar e não funciona.
O que você precisa saber antes de continuar lendo
O Telegram possui vários tipos de chats em grupo (abertos, fechados). Para esses chats, algumas funções (por exemplo, id) são diferentes, o que às vezes causa alguns problemas.
Vamos supor que estamos no final de 2019, e até mesmo o herói do nosso tempo, o conhecido Man-Orchestra (administrador, advogado, especialista em segurança da informação, programador e praticamente MVP) Evgeniy V. distingue a variável $i de um array, dominou os loops, veja se nos próximos anos dominará o Chocolatey e então Processamento paralelo com PowerShell и Paralelo ForEach-Object virá.
1. Pensamos no que nosso bot fará
Eu não tinha ideias, tive que pensar. Eu já escrevi um caderno de bot. Eu não queria fazer um bot “que enviasse algo para algum lugar”. Para se conectar ao Azure você precisa de um cartão de crédito, mas onde o aluno o consegue? Ressalta-se que nem tudo é tão ruim: as nuvens principais dão uma espécie de período de teste de graça (mas você ainda precisa de um número de cartão de crédito - e parece que vai ser debitado um dólar dele. Não me lembro se foi devolvido mais tarde.)
Sem AI ML não é tão interessante fazer um bot-pobre-poeta-tecelão.
Decidi fazer um bot que me lembrasse (ou não) as palavras em inglês do dicionário.
Para evitar mexer no banco de dados, o dicionário será armazenado em um arquivo de texto e atualizado manualmente.
Nesse caso, a tarefa é mostrar o básico do trabalho, e não fazer pelo menos um produto parcialmente acabado.
2. Experimentando o que e como pela primeira vez
Vamos criar uma pasta C:poshtranslate
Primeiro, vamos ver que tipo de PowerShell temos, vamos iniciar o ISE via start-run
ish powershell
ou encontre o Powershell ISE nos programas instalados.
Após o lançamento, o familiar “algum tipo de editor” será aberto; se não houver campo de texto, você pode clicar em “Arquivo - criar novo”.
Vejamos a versão do PowerShell - escreva no campo de texto:
get-host
e pressione F5.
O Powershell se oferecerá para salvar - “O script que você está prestes a executar será salvo.”, concordamos, e salve o arquivo do PowerShell com o nome em C: poshtranslate myfirstbotBT100.
Após o lançamento, na janela de texto inferior obtemos uma tabela de dados:
Name : Windows PowerShell ISE Host
Version : 5.1.(и так далее)
Eu tenho 5.1 alguma coisa, isso é o suficiente. Se você tem um Windows 7/8 antigo, não é grande coisa - embora o PowerShell precise ser atualizado para a versão 5 - por exemplo. instruções.
Digite Get-Date na linha de comando abaixo, pressione Enter, veja a hora, vá para a pasta raiz com o comando
cd
e limpe a tela com o comando cls (não, você não precisa usar rm)
Agora vamos verificar o que funciona e como - vamos escrever nem mesmo o código, mas duas linhas, e tentar entender o que elas fazem. Vamos comentar a linha get-host com o símbolo # e adicionar um pouco.
# Пример шаблона бота
# get-host
<# это пример многострочного комментария #>
$TimeNow = Get-Date
$TimeNow
(O interessante é que na lista suspensa de formatação de código no Habré há duas dúzias de opções - mas o Powershell não está lá. O Dos está lá. O Perl está lá.)
E vamos executar o código pressionando F5 ou ">" na GUI.
Obtemos a seguinte saída:
Saturday, December 8, 2019 21:00:50 PM (или что-то типа)
Agora vamos analisar essas duas linhas e alguns pontos interessantes para não voltarmos a isso no futuro.
Ao contrário do Pascal (e não só), o próprio PowerShell tenta determinar que tipo atribuir a uma variável; mais detalhes sobre isso estão escritos no artigo Programa educacional sobre digitação em linguagens de programação
Portanto, ao criar uma variável $TimeNow e atribuir a ela o valor da data e hora atuais (Get-Date), não precisamos nos preocupar muito com que tipo de dados estarão lá.
É verdade que esta ignorância pode doer mais tarde, mas isso fica para mais tarde. Abaixo no texto haverá um exemplo.
Vamos ver o que temos. Vamos executar (na linha de comando)
$TimeNow | Get-member
e obter uma página de texto incompreensível
Exemplo de texto incompreensível número 1
PS C:> $TimeNow | Get-member
TypeName: System.DateTime
Name MemberType Definition
---- ---------- ----------
Add <b>Method </b>datetime Add(timespan value)
..
DisplayHint NoteProperty DisplayHintType DisplayHint=DateTime
Date <b>Property </b>datetime Date {get;}
Year Property int Year {get;}
..
DateTime ScriptProperty System.Object DateTime {get=if ((& { Set-StrictMode -Version 1; $this.DisplayHint }) -ieq "Date")...
Como você pode ver, uma variável do tipo TypeName: System.DateTime foi criada com vários métodos (no sentido do que podemos fazer com este objeto variável) e propriedades.
Vamos ligar $TimeNow.DayOfYear - obtemos o número do dia do ano.
Vamos ligar $TimeNow.DayOfYear | Get-Member - pegue TypeName: System.Int32 e um grupo de métodos.
Vamos ligar $TimeNow.ToUniversalTime() - e obtenha a hora em UTC
depurador
Às vezes acontece que é necessário executar um programa até uma determinada linha e ver o estado do programa naquele momento. Para este propósito, o ISE possui uma função Debug - alternar ponto de interrupção
Coloque um ponto de interrupção em algum lugar no meio, execute essas duas linhas e veja como fica o intervalo.
3. Compreender a interação com o bot do Telegram
É claro que ainda mais literatura foi escrita sobre a interação com o bot, com todos os getpush e assim por diante, mas a questão da teoria pode ser considerada opcionalmente.
No nosso caso é necessário:
Aprenda a enviar algo por correspondência
Aprenda a obter algo por correspondência
3.1 Aprendendo a enviar algo por correspondência e receber dela
e na Federação Russa, neste ponto, recebemos o erro Não é possível conectar-se ao servidor remoto.
Ou não recebemos - depende da operadora de telecomunicações e se o proxy está configurado e funcionando
Bem, só falta adicionar um proxy. Observe que usar um proxy não criptografado e geralmente fraudulento é extremamente perigoso para sua saúde.
A tarefa de encontrar um proxy funcional não é muito difícil - a maioria dos proxies http publicados funcionam. Acho que o quinto funcionou para mim.
Sintaxe usando proxy:
Invoke-WebRequest -Uri $URL4SEND -Proxy $MyProxy
Se você receber uma mensagem no seu chat com um bot, está tudo bem, você pode seguir em frente. Caso contrário, continue a depuração.
Você pode ver no que sua string $URL4SEND se transforma e tentar solicitá-la no navegador, assim:
Write-Host "ParsedHtml"
$MyMessageGet.ParsedHtml # тут интересное
Write-Host "RawContent"
$MyMessageGet.RawContent # и тут интересное, но еще к тому же и читаемое.
Write-Host "Content"
$MyMessageGet.Content
Se tudo funcionar para você, você terá uma longa fila como:
Felizmente, no artigo publicado anteriormente Telegram bot para administrador de sistema esta linha (sim, de acordo com $MyMessageGet.RawContent | get-membro é System.String), já foi desmontado.
4. Processe o que você recebe (já sabemos como enviar algo)
Como já escrito aqui, as coisas mais necessárias estão no conteúdo. Vamos dar uma olhada mais de perto.
Primeiro, escreveremos mais algumas frases para o bot na interface da web ou no telefone
/message1
/message2
/message3
e procure no navegador o endereço que foi formado na variável $URLGET.
O que é isso? Algum objeto complexo de matrizes de objetos contendo um identificador de mensagem ponta a ponta, identificador de bate-papo, identificador de envio e muitas outras informações.
No entanto, não precisamos descobrir “que tipo de objeto é esse” – parte do trabalho já foi feito para nós. Vamos ver o que tem dentro:
Lendo mensagens recebidas ou parte 4
Write-Host "This is part 4" <# конечно эта строка нам не нужна в итоговом тексте, но по ней удобно искать. #>
$Content4Pars01 = ConvertFrom-Json $MyMessageGet.Content
$Content4Pars01 | Get-Member
$Content4Pars01.result
$Content4Pars01.result[0]
$Content4Pars01.result[0] | Get-Member
$Content4Pars01.result[0].update_id
$Content4Pars01.result[0].message
$Content4Pars01.result[0].message.text
$Content4Pars01.result[1].message.text
$Content4Pars01.result[2].message.text
5. O que devemos fazer agora?
Vamos salvar o arquivo resultante com o nome myfirstbotBT105 ou o que você preferir, alterar o título e comentar todo o código já escrito via
<#start comment 105 end comment 105#>
Agora precisamos decidir onde obter o dicionário (bem, onde - no disco, em um arquivo) e como ele ficará.
Claro, você pode escrever um dicionário enorme diretamente no texto do roteiro, mas isso não vem ao caso.
Então, vamos ver com o que o PowerShell pode funcionar normalmente.
Em geral, ele não se importa com qual arquivo trabalhar, não importa para nós.
Temos uma escolha: txt (você pode, mas por quê), csv, xml.
Podemos assistir a todos?
Vamos criar uma classe MyVocabClassExample1 e uma variável $MyVocabExample1
Noto que a classe é escrita sem $
algum código #5
write-host "This is part 5"
class MyVocabClassExample1 {
[string]$Original # слово
[string]$Transcript
[string]$Translate
[string]$Example
[int]$VocWordID # очень интересный момент. Использование int с его ограничениями может порой приводить к диким последствиям, для примера - недавний случай с SSD HPE. Изначально я не стал добавлять этот элемент, потом все же дописал и закомментировал.
}
$MyVocabExample1 = [MyVocabClassExample1]::new()
$MyVocabExample1.Original = "Apple"
$MyVocabExample1.Transcript = "[ ˈapəl ]"
$MyVocabExample1.Translate = "Яблоко"
$MyVocabExample1.Example = "An apple is a sweet, edible fruit produced by an apple tree (Malus domestica)"
# $MyVocabExample1.$VocWordID = 1
$MyVocabExample2 = [MyVocabClassExample1]::new()
$MyVocabExample2.Original = "Pear"
$MyVocabExample2.Transcript = "[ pe(ə)r ]"
$MyVocabExample2.Translate = "Груша"
$MyVocabExample2.Example = "The pear (/ˈpɛər/) tree and shrub are a species of genus Pyrus"
# $MyVocabExample1.$VocWordID = 2
Vamos tentar escrever isso em arquivos usando exemplar.
Como é fácil ver, o MS não se distingue particularmente pela sua lógica; para um procedimento semelhante, em um caso é usado -FilePath, em outro -Path.
Além disso, no terceiro arquivo o idioma russo desapareceu, no quarto arquivo aconteceu... bem, algo aconteceu. #TYPE Sistema.Object[] 00
# “Contagem”,”Comprimento”,”LongLength”,”Classificação”,”SyncRoot”,”IsReadOnly”,”IsFixedSize”,”IsSynchronized” #
Vamos reescrever um pouco:
Parece ter ajudado, mas ainda não gosto do formato.
Eu especialmente não gosto de não poder colocar linhas de um objeto diretamente em um arquivo.
A propósito, já que começamos a gravar arquivos, podemos começar a manter um log de inicialização? Temos o tempo como variável, podemos definir o nome do arquivo.
É verdade que ainda não há nada para escrever, mas você pode pensar na melhor forma de girar os logs.
Vamos tentar o xml por enquanto.
$MyFilenameExample06 = $ScriptDir + "Example06.xml"
$MyVocabExample4AsArray = Import-Clixml -Path $MyFilenameExample06
# $MyVocabExample4AsArray
# $MyVocabExample4AsArray[0]
# и немного о совершенно неочевидных нюансах. Powershell время от времени ведет себя не так, как вроде бы как бы стоило бы ожидать бы.
# например у меня эти два вывода отличаются
# Write-Output $MyVocabExample4AsArray
# write-host $MyVocabExample4AsArray
Voltemos à tarefa. Escrevemos um arquivo de teste, lemos, o formato de armazenamento é claro, se necessário, você pode escrever um pequeno editor de arquivos separado para adicionar e excluir linhas.
Deixe-me lembrá-lo de que a tarefa era fazer um pequeno bot de treinamento.
Formato de trabalho: envio o comando “exemplo” para o bot, o bot me envia uma palavra e uma transcrição selecionadas aleatoriamente e após 10 segundos me envia uma tradução e um comentário. Sabemos como ler comandos, também gostaríamos de aprender como selecionar e verificar proxies automaticamente e redefinir os contadores de mensagens para o esquecimento.
Vamos descomentar tudo o que foi comentado anteriormente como desnecessário, comentar os exemplos agora desnecessários com txt e csv e salvar o arquivo como versão B106
Oh sim. Vamos enviar algo para o bot novamente.
6. Envio de funções e muito mais
Antes de processar a recepção, é necessário criar uma função para enviar “pelo menos alguma coisa” que não seja uma mensagem de teste.
Claro que no exemplo teremos apenas um envio e apenas um processamento, mas e se precisarmos fazer várias vezes a mesma coisa?
É mais fácil escrever uma função. Assim, temos uma variável do tipo object $MyVocabExample4AsArray, lida do arquivo, na forma de um array de até dois elementos. Vamos ler.
Ao mesmo tempo, trataremos do relógio; precisaremos dele mais tarde (na verdade, neste exemplo não precisaremos dele :)
Algum código #6.1
Write-Output "This is Part 6"
$Timezone = (Get-TimeZone)
IF($Timezone.SupportsDaylightSavingTime -eq $True){
$TimeAdjust = ($Timezone.BaseUtcOffset.TotalSeconds + 3600) } # приведенное время
ELSE{$TimeAdjust = ($Timezone.BaseUtcOffset.TotalSeconds)
}
function MyFirstFunction($SomeExampleForFunction1){
$TimeNow = Get-Date
$TimeNow.ToUniversalTime()
# $MyText02 = $TimeNow + " " + $SomeExampleForFunction1 # и вот тут мы получим ошибку
$MyText02 = $SomeExampleForFunction1 + " " + $TimeNow # а тут не получим, кто догадается почему - тот молодец.
$URL4SendFromFunction = "https://api.telegram.org/bot$MyToken/sendMessage?chat_id=$MyChatID&text=$MyText02"
Invoke-WebRequest -Uri $URL4SendFromFunction -Proxy $MyProxy
}
Como você pode ver facilmente, a função chama $MyToken e $MyChatID, que foram codificados anteriormente.
Não há necessidade de fazer isso, e se $MyToken for um para cada bot, então $MyChatID mudará dependendo do chat.
No entanto, como este é um exemplo, iremos ignorá-lo por enquanto.
Como $MyVocabExample4AsArray não é um array, embora seja muito semelhante a um, então você não pode simplesmente aceitar solicite seu comprimento.
Mais uma vez teremos que fazer algo que não pode ser feito - pára-quedas não está de acordo com o código - pegue e conte
Algum código #6.2
$MaxRandomExample = 0
foreach ($Obj in $MyVocabExample4AsArray) {
$MaxRandomExample ++
}
Write-Output $MaxRandomExample
$RandomExample = Get-Random -Minimum 0 -Maximum ($MaxRandomExample)
$TextForExample1 = $MyVocabExample4AsArray[$RandomExample].Original
# MyFirstFunction($TextForExample1)
# или в одну строку
# MyFirstFunction($MyVocabExample4AsArray[Get-Random -Minimum 0 -Maximum ($MaxRandomExample -1)].Example)
# Угадайте сами, какой пример легче читается посторонними людьми.
Aleatória recurso interessante. Digamos que queremos receber 0 ou 1 (temos apenas dois elementos no array). Ao definir limites 0..1, obteremos “1”?
não - não vamos entender, temos um exemplo especial Exemplo 2: Obtenha um número inteiro aleatório entre 0 e 99 Get-Random -Maximum 100
Portanto, para 0..1 precisamos definir o tamanho 0..2, com o número máximo do elemento = 1.
7. Processamento de mensagens recebidas e comprimento máximo da fila
Onde paramos antes? temos a variável recebida $MyMessageGet
e $Content4Pars01 obtido dele, dos quais estamos interessados nos elementos do array Content4Pars01.result
Vamos analisar tudo o que foi recebido e enviar uma resposta se a mensagem foi /word
o caso da construção, o que alguns descrevem como if-elseif, é chamado no PowerShell através do interruptor. Ao mesmo tempo, o código abaixo usa a chave -wildcard, que é completamente desnecessária e até prejudicial.
Algum código #7.1
Write-Output "This is part 7"
Foreach ($Result in $Content4Pars01.result) # Да, можно сделать быстрее
{
switch -wildcard ($Result.message.text)
{
"/word" {MyFirstFunction($TextForExample1)}
}
}
Vamos executar o script algumas vezes. Obteremos a mesma palavra duas vezes para cada tentativa de execução, especialmente se cometermos um erro na implementação do aleatório.
Mas pare. Não enviamos /word novamente, então por que a mensagem está sendo processada novamente?
A fila de envio de mensagens para o bot tem comprimento finito (100 ou 200 mensagens, eu acho) e deve ser limpa manualmente.
É claro que isso está descrito na documentação, mas você precisa lê-la!
Neste caso, precisamos do parâmetro ?chat_id, e &timeout, &limit, &parse_mode=HTML e &disable_web_page_preview=true ainda não são necessários.
Documentação para API do telegrama está aqui Diz em branco e inglês: Identificador da primeira atualização a ser retornada. Deve ser maior em um que o maior entre os identificadores de atualizações recebidas anteriormente. Por padrão, as atualizações começam com a mais antiga não confirmado atualização são retornados. Uma atualização é considerada confirmada assim que getUpdates é chamado com um compensar superior do que seu update_id. O deslocamento negativo pode ser especificado para recuperar atualizações começando em -offset update do final da fila de atualizações. Todas as atualizações anteriores serão esquecidas.
Sim, e vamos redefini-lo e reescrever um pouco a função. Temos duas opções: passar a mensagem inteira para a função e processá-la inteiramente na função ou fornecer apenas o ID da mensagem e redefini-la. Por exemplo, o segundo parece mais simples.
Anteriormente, nossa string de consulta “todas as mensagens” parecia
Ninguém proíbe você primeiro de receber todas as mensagens, processá-las e somente após o processamento bem-sucedido da solicitação não confirmada -> confirmada.
Por que faz sentido ligar para confirmação após a conclusão de todo o processamento? Uma falha é possível no meio da execução e se, no exemplo de um chatbot gratuito, perder uma única mensagem não for nada especial, então se você estiver processando o salário de alguém ou uma transação com cartão, o resultado pode ser pior.
Mais algumas linhas de código
$LastMessageId = ($Content4Pars01.result | select -last 1).update_id #ошибку в этом месте предполагается исправить самостоятельно.
$URLGET1 = "https://api.telegram.org/bot$mytoken/getUpdates?offset=$LastMessageId&limit=100"
Invoke-WebRequest -Uri $URLGET1 -Method Get -Proxy $MyProxy
8. Em vez de uma conclusão
Funções básicas - leitura de mensagens, redefinição de fila, leitura de arquivo e gravação em arquivo são feitas e mostradas.
Restam apenas quatro coisas a fazer:
enviando a resposta correta a uma solicitação no chat
enviando uma resposta para QUALQUER chat ao qual o bot foi adicionado
executando código em um loop
iniciando um bot a partir do agendador do Windows.
Todas essas tarefas são simples e podem ser facilmente realizadas lendo a documentação sobre parâmetros como
Set-ExecutionPolicy irrestrito e -ExecutionPolicy Bypass
ciclo do formulário
$TimeToSleep = 3 # опрос каждые 3 секунды
$TimeToWork = 10 # минут
$HowManyTimes = $TimeToWork*60/$TimeToSleep # счетчик для цикла
$MainCounter = 0
for ($MainCounter=0; $MainCounter -le $HowManyTimes) {
sleep $TimeToSleep
$MainCounter ++